home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / demo / rotplnnr.lha / RouteEdit.c < prev    next >
C/C++ Source or Header  |  1994-08-21  |  88KB  |  2,963 lines

  1. // RouteEdit -- edits RoutePlanner files
  2.  
  3. #include <proto/asl.h>
  4. #include <proto/dos.h>
  5. #include <proto/exec.h>
  6. #include <proto/icon.h>
  7. #include <proto/utility.h>
  8. #include <proto/muimaster.h>
  9. #include <proto/intuition.h>
  10.  
  11. #include <clib/alib_protos.h>
  12.  
  13. #include <exec/memory.h>
  14. #include <utility/hooks.h>
  15.  
  16. #include <libraries/mui.h>
  17. #include <libraries/gadtools.h>
  18.  
  19. #include "RoutePlanner.h"
  20. #include "RouteEdit_rev.h"
  21.  
  22. #include <dos.h>
  23.  
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #include <stdio.h>
  27.  
  28. #include <reg.h>
  29.  
  30. extern struct Library *MUIMasterBase;
  31. extern struct Library *IconBase;
  32. extern struct Library *UtilityBase;
  33. extern struct IntuitionBase *IntuitionBase;
  34. extern struct Library *AslBase;
  35.  
  36. void SPrintf(char *outstr, char *fmt, ...);
  37. void AddRouteEntries(APTR list,struct RouteData *rd,ULONG rdcount,
  38.   ULONG citynumber);
  39. void RemoveRoute(ULONG routenumber);
  40. void RemoveCity(ULONG citynumber);
  41. void ReLink(void);
  42. BOOL RedoMemory(ULONG NeededCityEntries, ULONG NeededRouteEntries);
  43. void AddCityEntries(APTR list, struct CityData *cd, ULONG CityCount);
  44. BOOL OpenDatabase(char *filename);
  45. BOOL SaveDatabase(char *filename);
  46.  
  47. ULONG BreakRoute(ULONG rte, ULONG origin);
  48. APTR __saveds __asm constructor(register __a2 APTR pool,
  49.   register __a1 struct CityName *entry);
  50. void NullString(char *str, ULONG length);
  51. void SetColumn(struct RouteData *rd,ULONG rdcount,ULONG citynumber);
  52. ULONG InfoRequester(char *filename, BOOL mpr);
  53.  
  54. void NullString(char *str, ULONG length)
  55. {
  56.   ULONG i;
  57.   
  58.   for(i=0;i<length;i++)
  59.     str[i]='\0';
  60. }
  61.  
  62. // Special list constructors and destructors
  63. APTR __saveds __asm constructor(register __a2 APTR pool,
  64.   register __a1 struct CityName *entry)
  65. {
  66.   struct CityName *cn;
  67.   
  68.   if(cn=malloc(sizeof(struct CityName)))
  69.     {
  70.     CopyMem(entry,cn,sizeof(struct CityName));
  71.     }
  72.   
  73.   return cn;
  74. }
  75.  
  76. VOID __saveds __asm destructor(register __a2 APTR pool,
  77.   register __a1 struct CityName *entry);
  78.  
  79. VOID __saveds __asm destructor(register __a2 APTR pool,
  80.   register __a1 struct CityName *entry)
  81. {
  82.   free(entry);
  83. }
  84.  
  85. LONG __saveds __asm display(register __a2 char **array,
  86.   register __a1 struct CityName *cn);
  87.  
  88. LONG __saveds __asm display(register __a2 char **array,
  89.   register __a1 struct CityName *cn)
  90. {
  91.   *array=cn->cn_Name;
  92.   
  93.   return 0;
  94. }
  95.  
  96. LONG __saveds __asm compare(register __a1 struct CityName *cn1,
  97.   register __a2 struct CityName *cn2);
  98.  
  99. LONG __saveds __asm compare(register __a1 struct CityName *cn1,
  100.   register __a2 struct CityName *cn2)
  101. {
  102.   return(Stricmp(cn1->cn_Name,cn2->cn_Name));
  103. }
  104.  
  105. struct Hook comphook={{NULL,NULL},&compare,NULL,NULL};
  106. struct Hook consthook={{NULL,NULL},(HOOKFUNC)&constructor,NULL,NULL};
  107. struct Hook desthook={{NULL,NULL},(HOOKFUNC)&destructor,NULL,NULL};
  108. struct Hook disphook={{NULL,NULL},&display,NULL,NULL};
  109.  
  110. // Route constructors and destructors
  111. APTR __saveds __asm rteconst(register __a2 APTR pool,
  112.   register __a1 struct RouteData *entry);
  113.  
  114. APTR __saveds __asm rteconst(register __a2 APTR pool,
  115.   register __a1 struct RouteData *entry)
  116. {
  117.   struct RouteName *rn;
  118.   
  119.   if(rn=malloc(sizeof(struct RouteName)))
  120.     {
  121.     rn->rn_RouteID=entry->RouteID;
  122.     SPrintf(rn->rn_Name,"%s (%s, %s)",entry->Hiway,
  123.       entry->CityNum[entry->Colm[0]]->CityName,
  124.       entry->CityNum[entry->Colm[0]]->StateName);
  125.     }
  126.   
  127.   return rn;
  128. }
  129.  
  130. VOID __saveds __asm rtedest(register __a2 APTR pool,
  131.   register __a1 struct CityName *entry);
  132.  
  133. VOID __saveds __asm rtedest(register __a2 APTR pool,
  134.   register __a1 struct CityName *entry)
  135. {
  136.   free(entry);
  137. }
  138.  
  139. LONG __saveds __asm rtedisp(register __a2 char **array,
  140.   register __a1 struct RouteName *rn);
  141.  
  142. LONG __saveds __asm rtedisp(register __a2 char **array,
  143.   register __a1 struct RouteName *rn)
  144. {
  145.   *array=rn->rn_Name;
  146.   
  147.   return 0;
  148. }
  149.  
  150. LONG __saveds __asm rtecomp(register __a1 struct RouteName *rn1,
  151.   register __a2 struct RouteName *rn2);
  152.  
  153. LONG __saveds __asm rtecomp(register __a1 struct RouteName *rn1,
  154.   register __a2 struct RouteName *rn2)
  155. {
  156.   return(Stricmp(rn1->rn_Name,rn2->rn_Name));
  157. }
  158.  
  159. struct Hook rcomphook={{NULL,NULL},&rtecomp,NULL,NULL};
  160. struct Hook rconsthook={{NULL,NULL},(HOOKFUNC)&rteconst,NULL,NULL};
  161. struct Hook rdesthook={{NULL,NULL},(HOOKFUNC)&rtedest,NULL,NULL};
  162. struct Hook rdisphook={{NULL,NULL},&rtedisp,NULL,NULL};
  163.  
  164. // General Defines
  165. #define COPYRIGHT VERS" ("DATE") -- Copyright 1994 Chris Lawrence"
  166.  
  167. BOOL Authenticated;
  168.  
  169. APTR app=NULL, memptr=NULL, cdptr=NULL, rdptr=NULL, mainwindow=NULL;
  170. struct DiskObject *disko=NULL;
  171.  
  172. // These two pointers used by memory reallocation system
  173. struct CityData *cd;
  174. struct RouteData *rd;
  175. ULONG cdcount=0,rdcount=0;
  176.  
  177. struct DataBaseInfo dbi;
  178.  
  179. struct Registration *reg=NULL;
  180.  
  181. UWORD MeasureUnits;
  182.  
  183. void _STD_32767_killapp(void);
  184.  
  185. void _STD_32767_killapp(void)
  186. {
  187.   // SAS/C Autotermination function
  188.   
  189.   // This removes the application using MUI_DisposeObject. It is called
  190.   // when the program exits. Normal exits would also save the application
  191.   // object.
  192.   
  193.   if(memptr)
  194.     free(memptr);
  195.   else
  196.     {
  197.     if(cdptr) free(cdptr);
  198.     if(rdptr) free(rdptr);
  199.     }
  200.   
  201.   if(disko) FreeDiskObject(disko);
  202.   if(app) MUI_DisposeObject(app);
  203. }
  204.  
  205. APTR KeyPopButton(ULONG img, char key);
  206.  
  207. APTR KeyPopButton(ULONG img, char key)
  208. {
  209.   return (ImageObject,
  210.            ImageButtonFrame,
  211.            MUIA_ControlChar, key,
  212.            MUIA_Image_Spec, img,
  213.            MUIA_Image_FontMatch, TRUE,
  214.            MUIA_InputMode, MUIV_InputMode_RelVerify,
  215.            MUIA_Background, MUII_ButtonBack,
  216.            End);
  217. }
  218.  
  219. #define setinteger(obj,num) set(obj,MUIA_String_Integer,num)
  220.  
  221. #undef setstring
  222. void setstring(APTR object, char *str);
  223.  
  224. void setstring(APTR object, char *str)
  225. {
  226.   set(object,MUIA_String_Contents,str);
  227. }
  228.  
  229. void settext(APTR object, char *str);
  230.  
  231. void settext(APTR object, char *str)
  232. {
  233.   set(object,MUIA_Text_Contents,str);
  234. }
  235.  
  236. #undef KeyButton
  237. APTR KeyButton(char *label, char key);
  238.  
  239. APTR KeyButton(char *label, char key)
  240. {
  241.   return (TextObject,
  242.            ButtonFrame,
  243.            MUIA_Text_Contents, label,
  244.            MUIA_Text_PreParse, MUIX_C,
  245.            MUIA_Text_HiChar, key,
  246.            MUIA_ControlChar, key,
  247.            MUIA_InputMode, MUIV_InputMode_RelVerify,
  248.            MUIA_Background, MUII_ButtonBack,
  249.            MUIA_Weight, 25,
  250.            End);
  251. }
  252.  
  253. APTR SimpleText(char *text);
  254.  
  255. APTR SimpleText(char *text)
  256. {
  257.   return(TextObject,
  258.           TextFrame,
  259.           MUIA_Text_Contents, text,
  260.           MUIA_InputMode,     MUIV_InputMode_None,
  261.           MUIA_Background,    MUII_TextBack,
  262.           End);
  263. }
  264.  
  265. void ButtonBehave(APTR button, LONG notifyval);
  266.  
  267. void ButtonBehave(APTR button, LONG notifyval)
  268.   {
  269.   DoMethod((ULONG *)button,MUIM_Notify,MUIA_Pressed,FALSE,app,2,
  270.     MUIM_Application_ReturnID, notifyval);
  271.   }
  272.  
  273. void StringBehave(APTR string, LONG notifyval);
  274.  
  275. void StringBehave(APTR string, LONG notifyval)
  276.   {
  277.   DoMethod((ULONG *)string,MUIM_Notify,MUIA_String_Acknowledge,
  278.     MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, notifyval);
  279.   }
  280.  
  281. void StringReturn(APTR string, APTR window);
  282.  
  283. void StringReturn(APTR string, APTR window)
  284.   {
  285.   DoMethod(string,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,
  286.     window,3,MUIM_Set,MUIA_Window_ActiveObject,
  287.     MUIV_Window_ActiveObject_Next);
  288.   }
  289.  
  290. void CycleBehave(APTR cycle, LONG notifyval);
  291.  
  292. void CycleBehave(APTR cycle, LONG notifyval)
  293.   {
  294.   DoMethod((ULONG *)cycle,MUIM_Notify,MUIA_Cycle_Active,
  295.     MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, notifyval);
  296.   }
  297.  
  298. BOOL GetFile(char *filename, BOOL saverequest, char *tbar);
  299.  
  300. BOOL GetFile(char *filename, BOOL saverequest, char *tbar)
  301. {
  302.   static char file[40], dir[255], *c;
  303.   struct FileRequester *fr;
  304.   struct Window *win;
  305.   BOOL result;
  306.   
  307.   fr=MUI_AllocAslRequest(ASL_FileRequest,NULL);
  308.   if(!fr) return FALSE;
  309.   
  310.   get(mainwindow,MUIA_Window_Window,&win);
  311.   
  312.   set(app,MUIA_Application_Sleep,TRUE);
  313.   
  314.   if(Stricmp(filename,""))
  315.     {
  316.     strcpy(dir,filename);
  317.     c=PathPart(dir);
  318.     *c='\0';
  319.     
  320.     c=FilePart(filename);
  321.     strcpy(file,c);
  322.     }
  323.   else
  324.     {
  325.     strcpy(dir,"");
  326.     strcpy(file,"");
  327.     }
  328.   
  329.   if(MUI_AslRequestTags(fr,
  330.     ASLFR_Window, win,
  331.     ASLFR_TitleText, tbar,
  332.     ASLFR_Flags1, (saverequest ? FRF_DOSAVEMODE : 0),
  333.     ASLFR_RejectIcons, TRUE,
  334.     ASLFR_InitialDrawer, dir,
  335.     ASLFR_InitialFile, file,
  336.     TAG_DONE))
  337.     {
  338.     strcpy(filename,fr->fr_Drawer);
  339.     AddPart(filename,fr->fr_File,255);
  340.     
  341.     result=TRUE;
  342.     }
  343.   else
  344.     {
  345.     result=FALSE;
  346.     }
  347.  
  348.   set(app,MUIA_Application_Sleep,FALSE);
  349.   
  350.   if(fr) MUI_FreeAslRequest(fr);
  351.   
  352.   return result;
  353. }
  354.  
  355. // Gadget defines for ChooseCity
  356. #define CANCEL     (30)
  357. #define OK         (31)
  358. #define STRING     (32)
  359. #define CHANGELV   (33)
  360. #define ALL        (34)
  361.  
  362. ULONG ChooseCity(struct CityData *cd, ULONG CityCount, ULONG CurrentCity,
  363.   char *tbar);
  364.  
  365. ULONG ChooseCity(struct CityData *cd, ULONG CityCount, ULONG CurrentCity,
  366.   char *tbar)
  367. {
  368.   // Present requester for choosing a city.
  369.   // Return -2 if quit request received.
  370.   // Return -1 if canceled
  371.   
  372.   APTR citywindow, LV_Listview, BT_Ok, BT_Cancel, ST_CityName, BT_All;
  373.   APTR tempptr;
  374.   BOOL going=TRUE, exact;
  375.   ULONG sigs, choice, temp, i, found, entries;
  376.   static struct CityName *cn;
  377.   static char *tmp, cbuf[514], sbuf[128], compstr[256];
  378.   
  379.   set(app,MUIA_Application_Sleep,TRUE);
  380.   
  381.   citywindow=WindowObject,
  382.                MUIA_Window_Title,       tbar,
  383.                MUIA_Window_ScreenTitle, COPYRIGHT,
  384.                MUIA_Window_RefWindow,   mainwindow,
  385.                MUIA_Window_Menu,        MUIV_Window_Menu_NoMenu,
  386.                MUIA_Window_LeftEdge,    MUIV_Window_LeftEdge_Moused,
  387.                MUIA_Window_TopEdge,     MUIV_Window_TopEdge_Moused,
  388.                MUIA_Window_Height,      MUIV_Window_Height_Default,
  389.                MUIA_HelpNode,           "CityRequester",
  390.                
  391.                WindowContents,
  392.                VGroup,
  393.                  Child,LV_Listview=ListviewObject,
  394.                    MUIA_Listview_List, ListObject,
  395.                      MUIA_List_CompareHook, &comphook,
  396.                      MUIA_List_ConstructHook, &consthook,
  397.                      MUIA_List_DestructHook, &desthook,
  398.                      MUIA_List_DisplayHook, &disphook,
  399.                      MUIA_List_AdjustWidth, TRUE,
  400.                      InputListFrame,
  401.                      End,
  402.                    MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_None,
  403.                    End,
  404.                  Child,HGroup,
  405.                    Child, KeyLLabel2("Search:",'s'),
  406.                    Child, ST_CityName=KeyString("",70,'s'),
  407.                    Child, BT_All=KeyButton("All",'l'),
  408.                    End,
  409.                  Child,HGroup,
  410.                    Child, BT_Ok=KeyButton("Ok",'o'),
  411.                    Child, BT_Cancel=KeyButton("Cancel",'c'),
  412.                    MUIA_Group_SameWidth, TRUE,
  413.                    End,
  414.                  End,
  415.                End;
  416.   
  417.   if(citywindow)
  418.     {
  419.     DoMethod(app,OM_ADDMEMBER,citywindow);
  420.     
  421.     DoMethod(citywindow,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
  422.       app,2,MUIM_Application_ReturnID,CANCEL);
  423.     
  424.     DoMethod(LV_Listview,MUIM_Notify,MUIA_Listview_DoubleClick,TRUE,
  425.       app,2,MUIM_Application_ReturnID,OK);
  426.     
  427.     ButtonBehave(BT_Ok, OK);
  428.     ButtonBehave(BT_Cancel, CANCEL);
  429.     ButtonBehave(BT_All, ALL);
  430.     
  431.     DoMethod(LV_Listview,MUIM_Notify,MUIA_List_Active,MUIV_EveryTime,
  432.       app,2,MUIM_Application_ReturnID,CHANGELV);
  433.     
  434.     // Add entries to list & sort them
  435.     for(i=0;i<CityCount;i++)
  436.       {
  437.       cd[i].cd_Dummy=(unsigned char)cd[i].Displayed;
  438.       cd[i].Displayed=TRUE;
  439.       }
  440.     
  441.     AddCityEntries(LV_Listview,cd,CityCount);
  442.     
  443.     if(CurrentCity==(ULONG)-1)
  444.       {
  445.       set(LV_Listview,MUIA_List_Active,MUIV_List_Active_Off);
  446.       set(BT_Ok,MUIA_Disabled,TRUE);
  447.       }
  448.     else
  449.       {
  450.       BOOL found=FALSE;
  451.       
  452.       for(i=0;i<cdcount && !found;i++)
  453.         {
  454.         DoMethod(LV_Listview,MUIM_List_GetEntry,i,&cn);
  455.         
  456.         if(cn->cn_CityID==CurrentCity)
  457.           {
  458.           found=TRUE;
  459.           set(LV_Listview,MUIA_List_Active,i);
  460.           }
  461.         }
  462.       }
  463.     
  464.     DoMethod(citywindow,MUIM_Window_SetCycleChain,ST_CityName,
  465.       LV_Listview,NULL);
  466.     
  467.     set(citywindow,MUIA_Window_DefaultObject,LV_Listview);
  468.     
  469.     set(citywindow,MUIA_Window_ActiveObject,ST_CityName);
  470.     
  471.     set(ST_CityName,MUIA_String_AttachedList,LV_Listview);
  472.     
  473.     StringBehave(ST_CityName,STRING);
  474.     
  475.     set(citywindow,MUIA_Window_Open,TRUE);
  476.     
  477.     DoMethod(LV_Listview,MUIM_List_Jump,MUIV_List_Jump_Active);
  478.     
  479.     while(going)
  480.       {
  481.       switch(DoMethod(app,MUIM_Application_Input,&sigs))
  482.         { // Can't ignore MUIV_Application_ReturnID_Quit
  483.         case MUIV_Application_ReturnID_Quit:
  484.           choice=(ULONG)-2;
  485.           going=FALSE;
  486.           break;
  487.         
  488.         case CANCEL:
  489.           choice=(ULONG)-1;    
  490.           going=FALSE;
  491.           break;
  492.           
  493.         case CHANGELV:
  494.           get(LV_Listview,MUIA_List_Active,&temp);
  495.           set(BT_Ok,MUIA_Disabled,(temp==MUIV_List_Active_Off));
  496.           if(temp!=MUIV_List_Active_Off)
  497.             {
  498.             DoMethod(LV_Listview,MUIM_List_GetEntry,
  499.               MUIV_List_GetEntry_Active,&cn);
  500.             setstring(ST_CityName,cn->cn_Name);
  501.             }
  502.           break;
  503.         
  504.         case STRING:
  505.           // Do search thingy
  506.           get(LV_Listview,MUIA_List_Entries,&entries);
  507.           
  508.           get(ST_CityName,MUIA_String_Contents,&tmp);
  509.           strcpy(cbuf,tmp);
  510.           
  511.           set(LV_Listview,MUIA_List_Active,MUIV_List_Active_Off);
  512.           if(tmp=strchr(cbuf,','))
  513.             {
  514.             *tmp++='\0';
  515.             while(*tmp==' ') tmp++;
  516.             strcpy(sbuf,tmp);
  517.             }
  518.           else strcpy(sbuf,"");
  519.           
  520.           SPrintf(compstr,"%s#?,# %s#?",cbuf,sbuf);
  521.           
  522.           ParsePatternNoCase(compstr,cbuf,514);
  523.           
  524.           if(Stricmp(compstr,"#?,# #?"))
  525.             {
  526.             for(found=0,i=0,exact=FALSE;i<entries;i++)
  527.               {
  528.               DoMethod(LV_Listview,MUIM_List_GetEntry,i,&cn);
  529.               if(MatchPatternNoCase(cbuf,cn->cn_Name))
  530.                 {
  531.                 cd[cn->cn_CityID].Displayed=TRUE;
  532.                 found++;
  533.                 choice=i;
  534.                 get(ST_CityName,MUIA_String_Contents,&tmp);
  535.                 
  536.                 if(!Stricmp(tmp,cn->cn_Name))
  537.                   {
  538.                   exact=TRUE;
  539.                   temp=i;
  540.                   }
  541.                 }
  542.               else
  543.                 cd[cn->cn_CityID].Displayed=FALSE;
  544.               }
  545.             }
  546.           else
  547.             {
  548.             for(i=0;i<CityCount;i++)
  549.               cd[i].Displayed=TRUE;
  550.             found=2;
  551.             }
  552.           
  553.           if(found==0)
  554.             {
  555.             setstring(ST_CityName,"");
  556.             MUI_Request(app,citywindow,0,NULL,"_Ok","No cities matched");
  557.             set(citywindow,MUIA_Window_ActiveObject,ST_CityName);
  558.             }
  559.           else if(found==1 || exact)
  560.             {
  561.             set(LV_Listview,MUIA_List_Active,(exact ? temp : choice));
  562.             if(exact)
  563.               {
  564.               DoMethod(app,MUIM_Application_ReturnID,OK);
  565.               set(citywindow,MUIA_Window_ActiveObject,LV_Listview);
  566.               }
  567.             else
  568.               set(citywindow,MUIA_Window_ActiveObject,ST_CityName);
  569.             }
  570.           else
  571.             {
  572.             AddCityEntries(LV_Listview,cd,CityCount);
  573.             set(citywindow,MUIA_Window_ActiveObject,ST_CityName);
  574.             }
  575.           
  576.           break;
  577.         
  578.         case OK:
  579.           get(citywindow,MUIA_Window_ActiveObject,&tempptr);
  580.           if(tempptr==ST_CityName)
  581.             {
  582.             DoMethod(app,MUIM_Application_ReturnID,STRING);
  583.             }
  584.           else
  585.             {
  586.             DoMethod(LV_Listview,MUIM_List_GetEntry,
  587.               MUIV_List_GetEntry_Active,&cn);
  588.             if(cn)
  589.               {
  590.               get(ST_CityName,MUIA_String_Contents,&tmp);
  591.               
  592.               if(!Stricmp(cn->cn_Name,tmp))
  593.                 {
  594.                 choice=cn->cn_CityID;
  595.                 going=FALSE;
  596.                 }
  597.               else
  598.                 {
  599.                 DoMethod(app,MUIM_Application_ReturnID,STRING);
  600.                 }
  601.               }
  602.             }
  603.           break;
  604.         
  605.         case ALL:
  606.           for(i=0;i<CityCount;i++)
  607.             cd[i].Displayed=TRUE;
  608.             
  609.           AddCityEntries(LV_Listview,cd,CityCount);
  610.           set(citywindow,MUIA_Window_ActiveObject,ST_CityName);
  611.           break;
  612.         }
  613.       
  614.       if(going && sigs) Wait(sigs);
  615.       }
  616.     
  617.     for(i=0;i<CityCount;i++)
  618.       cd[i].Displayed=(BOOL)cd[i].cd_Dummy;
  619.     
  620.     set(citywindow,MUIA_Window_Open,FALSE);
  621.     DoMethod(app,OM_REMMEMBER,citywindow);
  622.     MUI_DisposeObject(citywindow);
  623.     }
  624.   else
  625.     MUI_RequestA(app,mainwindow,0,NULL,"_Ok","Couldn't create city requester.",NULL);
  626.   
  627.   set(app,MUIA_Application_Sleep,FALSE);
  628.   return(choice);
  629. }
  630.  
  631. void AddCityEntries(APTR list, struct CityData *cd, ULONG CityCount)
  632. {
  633.   ULONG i;
  634.   struct CityName cn;
  635.   
  636.   set(list,MUIA_List_Quiet,TRUE);
  637.   
  638.   DoMethod(list,MUIM_List_Clear,NULL);
  639.   
  640.   for(i=0;i<CityCount;i++)
  641.     {
  642.     if(cd[i].Displayed)
  643.       {
  644.       cn.cn_CityID=cd[i].CityID;
  645.       SPrintf(cn.cn_Name,"%s, %s",cd[i].CityName,cd[i].StateName);
  646.       DoMethod(list,MUIM_List_InsertSingle,&cn,MUIV_List_Insert_Sorted);
  647.       }
  648.     }
  649.   
  650.   set(list,MUIA_List_Quiet,FALSE);
  651. }
  652.  
  653. UWORD ConvertDist(UWORD srcDist, UWORD srcUnits, UWORD destUnits);
  654.  
  655. UWORD ConvertDist(UWORD srcDist, UWORD srcUnits, UWORD destUnits)
  656. {
  657.   ULONG work;
  658.   
  659.   if(srcUnits==UNITS_ENGLISH && destUnits==UNITS_METRIC)
  660.     {
  661.     work=(srcDist*16093)+8047;
  662.     work/=10000;
  663.     }
  664.   else if(srcUnits==UNITS_METRIC && destUnits==UNITS_ENGLISH)
  665.     {
  666.     work=(srcDist*10000)+5000;
  667.     work/=16093;
  668.     }
  669.   else work=srcDist;
  670.   
  671.   return (UWORD)work;
  672. }
  673.  
  674. ULONG EditRoute(ULONG RouteNumber, ULONG OriginCity, char *tbar);
  675. BOOL EditCity(ULONG id, char *title);
  676.  
  677. ULONG ModifiedProjectRequest(char *message);
  678.  
  679. ULONG ModifiedProjectRequest(char *message)
  680. {
  681.   return (ULONG)MUI_Request(app,mainwindow,0,NULL,"C_ontinue|*_Cancel",
  682.     message);
  683. }
  684.  
  685. #define NC_CANCEL    (100L)
  686. #define NC_OK        (101L)
  687.  
  688. BOOL EditCity(ULONG id, char *title)
  689. {
  690.   APTR twindow, ST_CityName, ST_StateName, BT_Ok, BT_Cancel;
  691.   APTR CB_IsJunction, CB_CoordsExist, ST_Latitude, ST_Longitude;
  692.   BOOL mpr=FALSE, going=TRUE;
  693.   ULONG sigs, i;
  694.   char *str, cbuf[20];
  695.   
  696.   set(app,MUIA_Application_Sleep,TRUE);
  697.   
  698.   twindow=WindowObject,
  699.             MUIA_Window_Title,       title,
  700.             MUIA_Window_ScreenTitle, COPYRIGHT,
  701.             MUIA_Window_RefWindow,   mainwindow,
  702.             MUIA_Window_NoMenus,     TRUE,
  703.             MUIA_Window_ID,          100,
  704.             MUIA_HelpNode,           "EditCity",
  705.             
  706.             WindowContents,
  707.             VGroup,
  708.               Child, ColGroup(2),
  709.                 Child, KeyLabel2("City:",'c'),
  710.                 Child, ST_CityName=KeyString(cd[id].CityName,32,'c'),
  711.                 Child, KeyLabel2("State:",'s'),
  712.                 Child, ST_StateName=KeyString(cd[id].StateName,22,'s'),
  713.                 End,
  714.               Child, MUI_MakeObject(MUIO_HBar,0),
  715.               Child, VGroup,
  716.                 Child, ColGroup(4),
  717.                   Child, HSpace(0),
  718.                   Child, CB_IsJunction=KeyCheckMark(cd[id].Intersection,'i'),
  719.                   Child, KeyLLabel1("Intersection",'i'),
  720.                   Child, HSpace(0),
  721.                   Child, HSpace(0),
  722.                   Child, CB_CoordsExist=KeyCheckMark(cd[id].CoordsExist,'u'),
  723.                   Child, KeyLLabel1("Use Coordinates",'u'),
  724.                   Child, HSpace(0),
  725.                   End,
  726.                 Child, ColGroup(2),
  727.                   Child, Label2("Latitude:"),
  728.                   Child, ST_Latitude=StringObject,
  729.                     StringFrame,
  730.                     MUIA_String_MaxLen,   8,
  731.                     MUIA_String_Contents, "",
  732.                     MUIA_String_Accept,   ".0123456789-",
  733.                     MUIA_String_Format, MUIV_String_Format_Right,
  734.                     MUIA_Disabled, !cd[id].CoordsExist,
  735.                     End,
  736.                   Child, Label2("Longitude:"),
  737.                   Child, ST_Longitude=StringObject,
  738.                     StringFrame,
  739.                     MUIA_String_MaxLen,   8,
  740.                     MUIA_String_Contents, "",
  741.                     MUIA_String_Accept,   ".0123456789-",
  742.                     MUIA_String_Format, MUIV_String_Format_Right,
  743.                     MUIA_Disabled, !cd[id].CoordsExist,
  744.                     End,
  745.                   End,
  746.                 End,
  747.               Child, HGroup,
  748.                 Child, BT_Ok=KeyButton("Ok",'o'),
  749.                 Child, BT_Cancel=KeyButton("Cancel",'<'),
  750.                 MUIA_Group_SameWidth, TRUE,
  751.                 End,
  752.               End,
  753.             End;
  754.   
  755.   if(twindow)
  756.     {
  757.     DoMethod(app,OM_ADDMEMBER,twindow);
  758.     
  759.     if(cd[id].CoordsExist)
  760.       {
  761.       sprintf(cbuf,"%-3.3f",cd[id].CityPos.latitude);
  762.       setstring(ST_Latitude,cbuf);
  763.       sprintf(cbuf,"%-3.3f",cd[id].CityPos.longitude);
  764.       setstring(ST_Longitude,cbuf);
  765.       }
  766.     
  767.     DoMethod(CB_CoordsExist,MUIM_Notify,MUIA_Selected,MUIV_EveryTime,
  768.       app,6,MUIM_MultiSet,MUIA_Disabled,MUIV_NotTriggerValue,
  769.       ST_Latitude,ST_Longitude,NULL);
  770.     
  771.     DoMethod(twindow,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,app,2,
  772.       MUIM_Application_ReturnID,NC_CANCEL);
  773.     
  774.     StringReturn(ST_CityName,twindow);
  775.     StringReturn(ST_Latitude,twindow);
  776.     StringReturn(ST_Longitude,twindow);
  777.     
  778.     StringBehave(ST_StateName,NC_OK);
  779.     
  780.     ButtonBehave(BT_Ok,NC_OK);
  781.     ButtonBehave(BT_Cancel,NC_CANCEL);
  782.     
  783.     DoMethod(twindow,MUIM_Window_SetCycleChain,ST_CityName,ST_StateName,
  784.       ST_Latitude,ST_Longitude,NULL);
  785.     
  786.     set(twindow,MUIA_Window_ActiveObject,ST_CityName);
  787.     
  788.     set(twindow,MUIA_Window_Open,TRUE);
  789.     
  790.     while(going)
  791.       {
  792.       switch(DoMethod(app,MUIM_Application_Input,&sigs))
  793.         { // Can't ignore MUIV_Application_ReturnID_Quit
  794.         case MUIV_Application_ReturnID_Quit:
  795.           mpr=FALSE;
  796.           going=FALSE;
  797.           DoMethod(app,MUIM_Application_ReturnID,
  798.             MUIV_Application_ReturnID_Quit);
  799.           break;
  800.         
  801.         case NC_OK:
  802.           get(ST_CityName,MUIA_String_Contents,&str);
  803.           strcpy(cd[id].CityName,str);
  804.           get(ST_StateName,MUIA_String_Contents,&str);
  805.           strcpy(cd[id].StateName,str);
  806.           
  807.           get(CB_IsJunction,MUIA_Selected,&i);
  808.           cd[id].Intersection=i;
  809.           
  810.           get(CB_CoordsExist,MUIA_Selected,&i);
  811.           cd[id].CoordsExist=i;
  812.           
  813.           if(i)
  814.             {
  815.             get(ST_Latitude,MUIA_String_Contents,&str);
  816.             cd[id].CityPos.latitude=atof(str);
  817.             
  818.             get(ST_Longitude,MUIA_String_Contents,&str);
  819.             cd[id].CityPos.longitude=atof(str);
  820.             }
  821.           
  822.           mpr=TRUE;
  823.           going=FALSE;
  824.           break;
  825.         
  826.         case NC_CANCEL:
  827.           mpr=FALSE;          
  828.           going=FALSE;
  829.           break;
  830.         } 
  831.       
  832.       if(going && sigs) Wait(sigs);
  833.       }
  834.     
  835.     set(twindow,MUIA_Window_Open,FALSE);
  836.     DoMethod(app,OM_REMMEMBER,twindow);
  837.     MUI_DisposeObject(twindow);
  838.     }
  839.   
  840.   set(app,MUIA_Application_Sleep,FALSE);
  841.   return mpr;
  842. }
  843.  
  844. #define ABOUT        (1L)
  845. #define HIDE         (2L)
  846. #define QUIT         MUIV_Application_ReturnID_Quit
  847. #define SAVE         (3L)
  848. #define SAVEAS       (4L)
  849. #define OPEN         (5L)
  850. #define NEW          (6L)
  851. #define INFO         (7L)
  852. #define SAVEASLOCKED (8L)
  853.  
  854. #define ADDROUTE    (10L)
  855. #define CHANGEROUTE (11L)
  856. #define REMOVEROUTE (12L)
  857. #define ADDCITY     (13L)
  858. #define REMOVECITY  (14L)
  859. #define EDITCITY    (15L)
  860. #define JUMP        (16L)
  861. #define BREAK       (17L)
  862. #define ALLCITIES   (18L)
  863.  
  864. #define LVMOVE      (20L)
  865. #define RETURNCITY  (21L)
  866.  
  867. #define MPRTRUE     (28L)
  868. #define UPDATEAVAIL (29L)
  869.  
  870. #define ABANDONPROJECT (1UL)
  871. #define SAVEPROJECT    (2UL)
  872. #define CANCELPROJECT  (0UL)
  873.  
  874. struct NewMenu mainmenu[]={
  875.   NM_TITLE, "Project", NULL, 0L, 0L, NULL,
  876.    NM_ITEM, "New", "N", 0L, 0L, (APTR)NEW,
  877.    NM_ITEM, "Open...", "O", 0L, 0L, (APTR)OPEN,
  878.    NM_ITEM, NM_BARLABEL, NULL, 0L, 0L, NULL,
  879.    NM_ITEM, "Save", "S", 0L, 0L, (APTR)SAVE,
  880.    NM_ITEM, "Save As...", "A", 0L, 0L, (APTR)SAVEAS,
  881.    NM_ITEM, "Save As Locked...", "L", 0L, 0L, (APTR)SAVEASLOCKED,
  882.    NM_ITEM, NM_BARLABEL, NULL, 0L, 0L, NULL,
  883.    NM_ITEM, "About...", "?", 0L, 0L, (APTR)ABOUT,
  884.    NM_ITEM, "Information...","I", 0L, 0L, (APTR)INFO,
  885.    NM_ITEM, NM_BARLABEL, NULL, 0L, 0L, NULL,
  886.    NM_ITEM, "Hide", "H", 0L, 0L, (APTR)HIDE,
  887.    NM_ITEM, "Quit", "Q", 0L, 0L, (APTR)QUIT,
  888.   NM_END, NULL, NULL, 0L, 0L, NULL
  889.   };
  890.  
  891. #define DisableInactive(object,i)\
  892.   set(object,MUIA_Disabled,i==MUIV_List_Active_Off)
  893.  
  894. #define SetTBar { SPrintf(tbar,"RouteEdit: %s%s",(mpr ? "* " : ""),\
  895.                   (Stricmp(DBase,"") ? DBase : "Untitled")); \
  896.                   set(mainwindow,MUIA_Window_Title,tbar); }
  897.  
  898. void main(int argc, char **argv)
  899. // Main user interface code
  900. //   Includes choose route requester
  901. {
  902.   STATIC char DBase[256]="", tbar[256]="";
  903.   APTR mainmenustrip, LV_Route, BT_AddCity;
  904.   APTR BT_RemoveCity, LV_City, ST_City, BT_AddRoute, BT_EditRoute;
  905.   APTR BT_RemoveRoute, BT_EditCity, tptr, BT_Jump, BT_Break, BT_All;
  906.   BPTR file;
  907.   BOOL going=TRUE, exact;
  908.   BOOL mpr=FALSE, ok;
  909.   ULONG sigs, temp, i, found, entries, choice;
  910.   static struct CityName *cn;
  911.   static struct RouteName *rn;
  912.   static char *tmp, cbuf[514], sbuf[128], compstr[256];
  913.   
  914.   if(!argc)
  915.     {
  916.     argc=_WBArgc;
  917.     argv=_WBArgv;
  918.     }
  919.   
  920.   app=ApplicationObject,
  921.         MUIA_Application_Title,      "RouteEdit",
  922.         MUIA_Application_Version,    "$VER: "VERS" ("DATE")",
  923.         MUIA_Application_Copyright,  "Copyright (C) 1994 Chris Lawrence",
  924.         MUIA_Application_Author,     "Chris Lawrence",
  925.         MUIA_Application_Description,"Highway Route Editor for RoutePlanner",
  926.         MUIA_Application_Base,       "ROUTEEDIT",
  927.         MUIA_Application_SingleTask, FALSE,
  928.         MUIA_Application_DiskObject,
  929.           disko=GetDiskObjectNew("PROGDIR:RouteEdit"),
  930.         MUIA_Application_HelpFile, "PROGDIR:RouteEdit.guide",
  931.         // MUIA_Application_Commands, COMMANDS,
  932.         
  933.         SubWindow,
  934.         mainwindow=WindowObject,
  935.           MUIA_Window_Title,       "RouteEdit: Untitled",
  936.           MUIA_Window_ID,          'REDT',
  937.           MUIA_Window_Menustrip,   
  938.             mainmenustrip=MUI_MakeObject(MUIO_MenustripNM,mainmenu,0),
  939.           MUIA_Window_ScreenTitle, COPYRIGHT,
  940.           MUIA_HelpNode, "MainWindow",
  941.           
  942.           WindowContents,
  943.           HGroup,
  944.             Child, VGroup,
  945.               MUIA_HelpNode, "CitiesHalf",
  946.               GroupFrameT("Cities"),
  947.               MUIA_Weight, 100,
  948.               Child, LV_City=ListviewObject,
  949.                 MUIA_Listview_Input, TRUE,
  950.                 MUIA_Listview_List, ListObject,
  951.                   MUIA_List_CompareHook, &comphook,
  952.                   MUIA_List_ConstructHook, &consthook,
  953.                   MUIA_List_DestructHook, &desthook,
  954.                   MUIA_List_DisplayHook, &disphook,
  955.                   MUIA_List_AdjustWidth, TRUE,
  956.                   InputListFrame,
  957.                   End,
  958.                 End,
  959.               Child, HGroup,
  960.                 Child, KeyLLabel2("Search:",'s'),
  961.                 Child, ST_City=StringObject,
  962.                   StringFrame,
  963.                   MUIA_String_AttachedList, LV_City,
  964.                   MUIA_String_MaxLen, 100,
  965.                   MUIA_ControlChar, 's',
  966.                   End,
  967.                 Child, BT_All=KeyButton("All",'l'),
  968.                 End,
  969.               Child, HGroup,
  970.                 MUIA_HelpNode, "CityButtons",
  971.                 Child, BT_AddCity=KeyButton("Add...",'d'),
  972.                 Child, BT_EditCity=KeyButton("Change...",'c'),
  973.                 Child, BT_RemoveCity=KeyButton("Remove",'m'),
  974.                 MUIA_Group_SameWidth, TRUE,
  975.                 End,
  976.               End,
  977.             Child, VGroup,
  978.               MUIA_Weight, 100,
  979.               Child, VGroup,
  980.                 MUIA_HelpNode, "RoutesHalf",
  981.                 GroupFrameT("Connections"),
  982.                 Child, LV_Route=ListviewObject,
  983.                     MUIA_Listview_Input, TRUE,
  984.                     MUIA_Listview_List, ListObject,
  985.                       MUIA_List_CompareHook, &rcomphook,
  986.                       MUIA_List_ConstructHook, &rconsthook,
  987.                       MUIA_List_DestructHook, &rdesthook,
  988.                       MUIA_List_DisplayHook, &rdisphook,
  989.                       MUIA_List_AdjustWidth, TRUE,
  990.                       InputListFrame,
  991.                       End,
  992.                     End,
  993.                 Child, HGroup,
  994.                   MUIA_HelpNode, "RouteButtons",
  995.                   Child, BT_AddRoute=KeyButton("Add...",'a'),
  996.                   Child, BT_EditRoute=KeyButton("Edit...",'e'),
  997.                   Child, BT_Break=KeyButton("Break...",'b'),
  998.                   Child, BT_Jump=KeyButton("Jump",'j'),
  999.                   Child, BT_RemoveRoute=KeyButton("Remove",'r'),
  1000.                   MUIA_Group_SameWidth, TRUE,
  1001.                   End,
  1002.                 End,
  1003.               End,
  1004.             End,
  1005.           End,
  1006.         End;
  1007.   
  1008.   if(!app)
  1009.     {
  1010.     MUI_Request(NULL,NULL,0L,"RouteEdit","Ok","Could not create application.");
  1011.     exit(20);
  1012.     }
  1013.   
  1014.   DoMethod(mainwindow,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
  1015.     app,2,MUIM_Application_ReturnID,QUIT);
  1016.   
  1017.   DoMethod(LV_Route,MUIM_Notify,MUIA_Listview_DoubleClick,TRUE,
  1018.     app,2,MUIM_Application_ReturnID,CHANGEROUTE);
  1019.     
  1020.   DoMethod(LV_City,MUIM_Notify,MUIA_List_Active,MUIV_EveryTime,
  1021.     app,2,MUIM_Application_ReturnID,LVMOVE);
  1022.   
  1023.   DoMethod(LV_Route,MUIM_Notify,MUIA_List_Active,MUIV_EveryTime,
  1024.     app,2,MUIM_Application_ReturnID,UPDATEAVAIL);
  1025.   
  1026.   set(ST_City,MUIA_String_AttachedList,LV_City);
  1027.   
  1028.   ButtonBehave(BT_AddRoute, ADDROUTE);
  1029.   ButtonBehave(BT_EditRoute, CHANGEROUTE);
  1030.   ButtonBehave(BT_RemoveRoute, REMOVEROUTE);
  1031.   ButtonBehave(BT_AddCity, ADDCITY);
  1032.   ButtonBehave(BT_RemoveCity, REMOVECITY);
  1033.   ButtonBehave(BT_All, ALLCITIES);
  1034.   
  1035.   StringBehave(ST_City, RETURNCITY);
  1036.   
  1037.   DoMethod(BT_EditCity,MUIM_Notify,MUIA_Pressed,FALSE,
  1038.     mainwindow,3,MUIM_Set,MUIA_Window_ActiveObject,LV_City);
  1039.   
  1040.   ButtonBehave(BT_EditCity, EDITCITY);
  1041.   ButtonBehave(BT_Jump, JUMP);
  1042.   ButtonBehave(BT_Break, BREAK);
  1043.   
  1044.   DoMethod(LV_City,MUIM_Notify,MUIA_Listview_DoubleClick,TRUE,
  1045.     app,2,MUIM_Application_ReturnID,EDITCITY);
  1046.   
  1047.   DoMethod(mainwindow,MUIM_Window_SetCycleChain,LV_City,ST_City,
  1048.     LV_Route,NULL);
  1049.   
  1050.   file=Open("PROGDIR:RouteEdit.key",MODE_OLDFILE);
  1051.   if(!file)
  1052.     {
  1053.     file=Open("s:RouteEdit.key",MODE_OLDFILE);
  1054.     if(!file)
  1055.       {
  1056.       file=Open("s:Global_CTS.key",MODE_OLDFILE);
  1057.       }
  1058.     }
  1059.     
  1060.   if(file)
  1061.     {
  1062.     reg=malloc(sizeof(struct Registration));
  1063.     if(reg)
  1064.       {
  1065.       if(FRead(file,reg,sizeof(struct Registration),1))
  1066.         {
  1067.         if(!(Authenticated=Authenticate(reg,CTS_ROUTEEDIT)))
  1068.           {
  1069.           free(reg);
  1070.           reg=NULL;
  1071.           }
  1072.         }
  1073.       else
  1074.         {
  1075.         free(reg);
  1076.         reg=NULL;
  1077.         }
  1078.       }
  1079.     Close(file);
  1080.     }
  1081.   
  1082.   if(!reg || !Authenticated)
  1083.     DoMethod(mainwindow,MUIM_Window_SetMenuState,SAVEASLOCKED,FALSE);
  1084.   
  1085.   set(mainwindow,MUIA_Window_Open,TRUE);
  1086.   get(mainwindow,MUIA_Window_Open,&i);
  1087.   if(!i)
  1088.     {
  1089.     MUI_Request(app,NULL,0,NULL,"_Ok","Couldn't open main window.");
  1090.     exit(20);
  1091.     }
  1092.   
  1093.   DoMethod(app,MUIM_Application_ReturnID,UPDATEAVAIL);
  1094.   
  1095.   if(argc>1)
  1096.     {
  1097.     set(app,MUIA_Application_Sleep,TRUE);
  1098.     if(OpenDatabase(argv[argc-1]))
  1099.       {
  1100.       strcpy(DBase,argv[argc-1]);
  1101.       mpr=FALSE;
  1102.       SetTBar;
  1103.       
  1104.       for(i=0;i<cdcount;i++)
  1105.         cd[i].Displayed=TRUE;
  1106.       
  1107.       setstring(ST_City,"");
  1108.       AddCityEntries(LV_City,cd,cdcount);
  1109.       
  1110.       if(rdcount)
  1111.         {
  1112.         MeasureUnits=rd[0].Units;
  1113.         }
  1114.       }
  1115.     else
  1116.       {
  1117.       MUI_Request(app,mainwindow,0,NULL,"_Ok",
  1118.         "Unable to open database %s.",argv[argc-1]);
  1119.       }
  1120.     
  1121.     set(app,MUIA_Application_Sleep,FALSE);
  1122.     }
  1123.   
  1124.   while(going)
  1125.     {
  1126.     switch(DoMethod(app,MUIM_Application_Input,&sigs))
  1127.       { // Can't ignore MUIV_Application_ReturnID_Quit
  1128.       case 0:
  1129.         break;
  1130.       
  1131.       case MUIV_Application_ReturnID_Quit:
  1132.         get(app,MUIA_Application_ForceQuit,&temp);
  1133.         if(mpr && !temp)
  1134.           i=ModifiedProjectRequest("Do you want to quit without\n"
  1135.             "saving the current database?");
  1136.         else i=ABANDONPROJECT;
  1137.         
  1138.         if(i==ABANDONPROJECT)
  1139.           {
  1140.           going=FALSE;
  1141.           }
  1142.         else if(i==SAVEPROJECT)
  1143.           {
  1144.           DoMethod(app,MUIM_Application_ReturnID,SAVE);
  1145.           DoMethod(app,MUIM_Application_ReturnID,QUIT);
  1146.           }
  1147.         break;
  1148.       
  1149.       case ABOUT:
  1150.         get(mainwindow,MUIA_Window_ActiveObject,&i);
  1151.         if(reg && Authenticated)
  1152.           {
  1153.           MUI_Request(app,mainwindow,0,NULL,(char *)"_Ok",
  1154.             (char *)MUIX_C""
  1155.             VERS" ("DATE")\n\n"
  1156.             "Map Editor for RoutePlanner\n"
  1157.             "© 1994 Chris Lawrence\n"
  1158.             "All rights reserved\n\n"
  1159.             "Registered to:\n"
  1160.             "%s (%s)\n\n"
  1161.             "This application uses MUI\n"
  1162.             "MUI is © 1993-94 Stefan Stuntz\n\n"
  1163.             "Compiled on "__DATE__,
  1164.             reg->Name,reg->EMail);
  1165.           }
  1166.         else
  1167.           {
  1168.           MUI_Request(app,mainwindow,0,NULL,(char *)"_Ok",
  1169.             (char *)MUIX_C""
  1170.             VERS" ("DATE")\n\n"
  1171.             "Map Editor for RoutePlanner\n"
  1172.             "© 1994 Chris Lawrence\n"
  1173.             "All rights reserved\n\n"
  1174.             "This application uses MUI\n"
  1175.             "MUI is © 1993-94 Stefan Stuntz\n\n"
  1176.             "Compiled on "__DATE__);
  1177.           }
  1178.         set(mainwindow,MUIA_Window_ActiveObject,i);
  1179.         break;
  1180.       
  1181.       case INFO:
  1182.         if(Stricmp(DBase,""))
  1183.           {
  1184.           tmp=DBase;
  1185.           }
  1186.         else
  1187.           {
  1188.           tmp="Untitled";
  1189.           }
  1190.         
  1191.         get(mainwindow,MUIA_Window_ActiveObject,&i);
  1192.         set(app,MUIA_Application_Sleep,TRUE);
  1193.         
  1194.         temp=InfoRequester(tmp,mpr);
  1195.         if(temp!=QUIT)
  1196.           {
  1197.           mpr=temp;
  1198.           SetTBar;
  1199.           set(mainwindow,MUIA_Window_ActiveObject,i);
  1200.           }
  1201.         else
  1202.           DoMethod(app,MUIM_Application_ReturnID,QUIT);
  1203.         
  1204.         set(app,MUIA_Application_Sleep,FALSE);
  1205.         break;
  1206.       
  1207.       case HIDE:
  1208.         set(app,MUIA_Application_Iconified,TRUE);
  1209.         break;
  1210.       
  1211.       case NEW:
  1212.         if(mpr)
  1213.           i=ModifiedProjectRequest("Do you want to start a new database\n"
  1214.             "without saving the current one?");
  1215.         else i=ABANDONPROJECT;
  1216.         
  1217.         if(i==ABANDONPROJECT)
  1218.           {
  1219.           if(RedoMemory(0,0))
  1220.             {
  1221.             strcpy(DBase,"");
  1222.             SetTBar;
  1223.             cdcount=0;
  1224.             rdcount=0;
  1225.             
  1226.             ReLink();
  1227.             
  1228.             mpr=FALSE;
  1229.             
  1230.             AddCityEntries(LV_City,cd,cdcount);
  1231.             DoMethod(app,MUIM_Application_ReturnID,UPDATEAVAIL);
  1232.             }
  1233.           }
  1234.         else if(i==SAVEPROJECT)
  1235.           {
  1236.           DoMethod(app,MUIM_Application_ReturnID,SAVE);
  1237.           DoMethod(app,MUIM_Application_ReturnID,NEW);
  1238.           }
  1239.         break;
  1240.       
  1241.       case OPEN:
  1242.         if(mpr)
  1243.           i=ModifiedProjectRequest("Do you want to open another file\n"
  1244.             "without saving the current one?");
  1245.         else i=ABANDONPROJECT; 
  1246.         
  1247.         if(i==ABANDONPROJECT)
  1248.           {
  1249.           strcpy(cbuf,DBase);
  1250.           
  1251.           if(GetFile(cbuf,FALSE,"Open database..."))
  1252.             {
  1253.             set(app,MUIA_Application_Sleep,TRUE);
  1254.             if(OpenDatabase(cbuf))
  1255.               {
  1256.               strcpy(DBase,cbuf);
  1257.               mpr=FALSE;
  1258.               SetTBar;
  1259.               
  1260.               for(i=0;i<cdcount;i++)
  1261.                 cd[i].Displayed=TRUE;
  1262.               
  1263.               setstring(ST_City,"");
  1264.               AddCityEntries(LV_City,cd,cdcount);
  1265.               DoMethod(app,MUIM_Application_ReturnID,UPDATEAVAIL);
  1266.               
  1267.               if(rdcount)
  1268.                 {
  1269.                 MeasureUnits=rd[0].Units;
  1270.                 }
  1271.               }
  1272.             else
  1273.               {
  1274.               MUI_Request(app,mainwindow,0,NULL,"_Ok",
  1275.                 "Unable to open database %s.",cbuf);
  1276.               }
  1277.             set(app,MUIA_Application_Sleep,FALSE);
  1278.             }
  1279.           }
  1280.         else if(i==SAVEPROJECT)
  1281.           {
  1282.           DoMethod(app,MUIM_Application_ReturnID,SAVE);
  1283.           DoMethod(app,MUIM_Application_ReturnID,OPEN);
  1284.           }
  1285.         break;
  1286.       
  1287.       case SAVEAS:
  1288.         // Alters filename, does a SAVE call
  1289.         if(GetFile(DBase,TRUE,"Save database as..."))
  1290.           {
  1291.           SetTBar;
  1292.           DoMethod(app,MUIM_Application_ReturnID,SAVE);
  1293.           }
  1294.         break;
  1295.         
  1296.       case SAVE:
  1297.         if(!Stricmp(DBase,""))
  1298.           {
  1299.           DoMethod(app,MUIM_Application_ReturnID,SAVEAS);
  1300.           }
  1301.         else
  1302.           {
  1303.           set(app,MUIA_Application_Sleep,TRUE);
  1304.           
  1305.           dbi.dbi_AuthorCode=(ULONG)~0;
  1306.           dbi.dbi_Security=DoFunkyThing(cdcount+rdcount+dbi.dbi_AuthorCode+
  1307.             StringSum(dbi.dbi_Author)+StringSum(dbi.dbi_EMail));
  1308.           
  1309.           if(SaveDatabase(DBase))
  1310.             {
  1311.             mpr=FALSE;
  1312.             SetTBar;
  1313.             }
  1314.           else
  1315.             {
  1316.             MUI_Request(app,mainwindow,0,NULL,"_Ok",
  1317.               "Unable to save database.");
  1318.             }
  1319.           set(app,MUIA_Application_Sleep,FALSE);
  1320.           }
  1321.         break;
  1322.       
  1323.       case SAVEASLOCKED:
  1324.         // Alters filename, does a SAVE call
  1325.         if(reg && Authenticated &&
  1326.           GetFile(DBase,TRUE,"Save locked database as..."))
  1327.           {
  1328.           set(app,MUIA_Application_Sleep,TRUE);
  1329.           SetTBar;
  1330.           
  1331.           dbi.dbi_AuthorCode=(ULONG)reg->ActualNumber;
  1332.           strcpy(dbi.dbi_Author,reg->Name);
  1333.           strcpy(dbi.dbi_EMail,reg->EMail);
  1334.           
  1335.           dbi.dbi_Security=DoFunkyThing(cdcount+rdcount+dbi.dbi_AuthorCode+
  1336.             StringSum(dbi.dbi_Author)+StringSum(dbi.dbi_EMail));
  1337.           
  1338.           if(SaveDatabase(DBase))
  1339.             {
  1340.             mpr=FALSE;
  1341.             SetTBar;
  1342.             }
  1343.           else
  1344.             {
  1345.             MUI_Request(app,mainwindow,0,NULL,"_Ok",
  1346.               "Unable to save database.");
  1347.             }
  1348.           set(app,MUIA_Application_Sleep,FALSE);
  1349.           }
  1350.         break;
  1351.       
  1352.       case ADDCITY:
  1353.         if(RedoMemory(cdcount+1,rdcount))
  1354.           {
  1355.           ReLink();
  1356.           
  1357.           get(LV_City,MUIA_List_Active,&i);
  1358.           
  1359.           memset(&cd[cdcount],'\0',sizeof(cd[cdcount]));
  1360.           cd[cdcount].Displayed=TRUE;
  1361.           cd[cdcount].CityID=cdcount;
  1362.           
  1363.           set(mainwindow,MUIA_Window_Sleep,TRUE);
  1364.           
  1365.           ok=EditCity(cdcount,"Add new city...");
  1366.           if(ok)
  1367.             {
  1368.             struct CityName tname;
  1369.             
  1370.             tname.cn_CityID=cdcount;
  1371.             SPrintf(tname.cn_Name,"%s, %s",cd[cdcount].CityName,
  1372.               cd[cdcount].StateName);
  1373.             
  1374.             setstring(ST_City,tname.cn_Name);
  1375.             
  1376.             DoMethod(LV_City,MUIM_List_InsertSingle,&tname,
  1377.               MUIV_List_Insert_Sorted);
  1378.             
  1379.             get(LV_City,MUIA_List_Entries,&entries);
  1380.             for(i=0;i<entries;i++)
  1381.               {
  1382.               DoMethod(LV_City,MUIM_List_GetEntry,i,&cn);
  1383.               if(cn->cn_CityID==cdcount) temp=i;
  1384.               }
  1385.             
  1386.             cdcount++;
  1387.             ReLink();
  1388.             set(LV_City,MUIA_List_Active,temp);
  1389.             mpr=TRUE;
  1390.             SetTBar;
  1391.             }
  1392.           else
  1393.             {
  1394.             RedoMemory(cdcount,rdcount);
  1395.             ReLink();
  1396.             
  1397.             DoMethod(LV_City,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,
  1398.               &cn);
  1399.             if(cn) SetColumn(rd,rdcount,cn->cn_CityID);
  1400.             }
  1401.           
  1402.           set(mainwindow,MUIA_Window_Sleep,FALSE);
  1403.           }
  1404.         break;
  1405.       
  1406.       case EDITCITY:
  1407.         get(mainwindow,MUIA_Window_ActiveObject,&tptr);
  1408.         if(tptr==ST_City)
  1409.           {
  1410.           DoMethod(app,MUIM_Application_ReturnID,RETURNCITY);
  1411.           }
  1412.         else
  1413.           {
  1414.           DoMethod(LV_City,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&cn);
  1415.           if(cn)
  1416.             {
  1417.             ok=EditCity(cn->cn_CityID,"Edit city...");
  1418.             if(ok)
  1419.               {
  1420.               struct CityName tname;
  1421.               
  1422.               found=cn->cn_CityID;
  1423.               
  1424.               set(LV_City,MUIA_List_Quiet,TRUE);
  1425.               DoMethod(LV_City,MUIM_List_Remove,MUIV_List_Remove_Active);
  1426.               
  1427.               tname.cn_CityID=found;
  1428.               SPrintf(tname.cn_Name,"%s, %s",cd[found].CityName,
  1429.                 cd[found].StateName);
  1430.               
  1431.               setstring(ST_City,tname.cn_Name);
  1432.               
  1433.               DoMethod(LV_City,MUIM_List_InsertSingle,&tname,
  1434.                 MUIV_List_Insert_Sorted);
  1435.               
  1436.               get(LV_City,MUIA_List_Entries,&entries);
  1437.               for(i=0;i<entries;i++)
  1438.                 {
  1439.                 DoMethod(LV_City,MUIM_List_GetEntry,i,&cn);
  1440.                 if(cn->cn_CityID==found) temp=i;
  1441.                 }
  1442.               
  1443.               set(LV_City,MUIA_List_Active,temp);
  1444.               set(LV_City,MUIA_List_Quiet,FALSE);
  1445.               mpr=TRUE;
  1446.               SetTBar;
  1447.               }
  1448.             }
  1449.           }
  1450.         break;
  1451.       
  1452.       case REMOVECITY:
  1453.         DoMethod(LV_City,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&cn);
  1454.         if(cn)
  1455.           {
  1456.           set(mainwindow,MUIA_Window_Sleep,TRUE);
  1457.           
  1458.           get(LV_City,MUIA_List_Active,&i);
  1459.           RemoveCity(cn->cn_CityID);
  1460.           AddCityEntries(LV_City,cd,cdcount);
  1461.           set(LV_City,MUIA_List_Active,i);
  1462.           
  1463.           set(mainwindow,MUIA_Window_Sleep,FALSE);
  1464.           mpr=TRUE;
  1465.           SetTBar;
  1466.           }
  1467.         break;
  1468.       
  1469.       case ADDROUTE:
  1470.         DoMethod(LV_City,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&cn);
  1471.         if(cn)
  1472.           {
  1473.           if(RedoMemory(cdcount,rdcount+1))
  1474.             {
  1475.             memset(&rd[rdcount],'\0',sizeof(rd[rdcount]));
  1476.             
  1477.             rd[rdcount].Colm[0]=1;
  1478.             rd[rdcount].CityID[0]=cn->cn_CityID;
  1479.             rd[rdcount].CityID[1]=(UWORD)-1;
  1480.             rd[rdcount].SpeedCode=USE_SPEED;
  1481.             rd[rdcount].Units=MeasureUnits;
  1482.             rd[rdcount].RouteID=rdcount;
  1483.             
  1484.             temp=EditRoute(rdcount,cn->cn_CityID,"Add route segment");
  1485.             
  1486.             if(temp==(ULONG)-3)
  1487.               {
  1488.               ReLink();
  1489.               DoMethod(app,MUIM_Application_ReturnID,QUIT);
  1490.               }
  1491.             else if(temp==(ULONG)-2)
  1492.               {
  1493.               ULONG count,num;
  1494.               
  1495.               found=rdcount;
  1496.               rdcount++;
  1497.               ReLink();
  1498.               
  1499.               AddRouteEntries(LV_Route,rd,rdcount,cn->cn_CityID);
  1500.               
  1501.               get(LV_Route,MUIA_List_Entries,&count);
  1502.               
  1503.               for(i=0;i<count;i++)
  1504.                 {
  1505.                 DoMethod(LV_Route,MUIM_List_GetEntry,i,&rn);
  1506.                 if(rn->rn_RouteID==found) num=i;
  1507.                 }
  1508.               
  1509.               set(LV_Route,MUIA_List_Active,num);
  1510.               mpr=TRUE;
  1511.               SetTBar;
  1512.               }
  1513.             else
  1514.               {
  1515.               RedoMemory(cdcount,rdcount);
  1516.               ReLink();
  1517.               SetColumn(rd,rdcount,cn->cn_CityID);
  1518.               }
  1519.             }
  1520.           }
  1521.         break;
  1522.       
  1523.       case CHANGEROUTE:
  1524.         DoMethod(LV_Route,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&rn);
  1525.         DoMethod(LV_City,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&cn);
  1526.         if(rn && cn)
  1527.           {
  1528.           get(LV_Route,MUIA_List_Active,&i);
  1529.           temp=EditRoute(rn->rn_RouteID,cn->cn_CityID,
  1530.             "Edit route segment");
  1531.           
  1532.           if(temp==(ULONG)-3)
  1533.             {
  1534.             DoMethod(app,MUIM_Application_ReturnID,QUIT);
  1535.             }
  1536.           else if(temp==(ULONG)-2)
  1537.             {
  1538.             ULONG count,num;
  1539.             
  1540.             ReLink();
  1541.             AddRouteEntries(LV_Route,rd,rdcount,cn->cn_CityID);
  1542.             
  1543.             found=rn->rn_RouteID;
  1544.             get(LV_Route,MUIA_List_Entries,&count);
  1545.             
  1546.             for(i=0;i<count;i++)
  1547.               {
  1548.               DoMethod(LV_Route,MUIM_List_GetEntry,i,&rn);
  1549.               if(rn->rn_RouteID==found) num=i;
  1550.               }
  1551.             
  1552.             set(LV_Route,MUIA_List_Active,num);
  1553.             mpr=TRUE;
  1554.             SetTBar;
  1555.             }
  1556.           else
  1557.             {
  1558.             SetColumn(rd,rdcount,cn->cn_CityID);
  1559.             }
  1560.           }
  1561.         break;
  1562.       
  1563.       case BREAK:
  1564.         DoMethod(LV_Route,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&rn);
  1565.         DoMethod(LV_City,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&cn);
  1566.         if(rn && cn)
  1567.           {
  1568.           get(LV_Route,MUIA_List_Active,&i);
  1569.           temp=BreakRoute(rn->rn_RouteID,cn->cn_CityID);
  1570.           
  1571.           if(temp==(ULONG)-3)
  1572.             {
  1573.             DoMethod(app,MUIM_Application_ReturnID,QUIT);
  1574.             }
  1575.           else if(temp==(ULONG)-2)
  1576.             {
  1577.             ULONG count,num;
  1578.             
  1579.             ReLink();
  1580.             AddRouteEntries(LV_Route,rd,rdcount,cn->cn_CityID);
  1581.             
  1582.             found=rn->rn_RouteID;
  1583.             get(LV_Route,MUIA_List_Entries,&count);
  1584.             
  1585.             for(i=0;i<count;i++)
  1586.               {
  1587.               DoMethod(LV_Route,MUIM_List_GetEntry,i,&rn);
  1588.               if(rn->rn_RouteID==found) num=i;
  1589.               }
  1590.             
  1591.             set(LV_Route,MUIA_List_Active,num);
  1592.             mpr=TRUE;
  1593.             SetTBar;
  1594.             }
  1595.           else
  1596.             {
  1597.             SetColumn(rd,rdcount,cn->cn_CityID);
  1598.             }
  1599.           }
  1600.         break;
  1601.       
  1602.       case REMOVEROUTE:
  1603.         DoMethod(LV_Route,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&rn);
  1604.         DoMethod(LV_City,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&cn);
  1605.         if(rn && cn)
  1606.           {
  1607.           get(LV_Route,MUIA_List_Active,&i);
  1608.           RemoveRoute(rn->rn_RouteID);
  1609.           AddRouteEntries(LV_Route,rd,rdcount,cn->cn_CityID);
  1610.           set(LV_Route,MUIA_List_Active,i);
  1611.           mpr=TRUE;
  1612.           SetTBar;
  1613.           }
  1614.         break;
  1615.       
  1616.       case JUMP:
  1617.         DoMethod(LV_Route,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&rn);
  1618.         if(rn)
  1619.           {
  1620.           set(mainwindow,MUIA_Window_Sleep,TRUE);
  1621.           
  1622.           i=rd[rn->rn_RouteID].Colm[0];
  1623.           found=rd[rn->rn_RouteID].CityID[i];
  1624.           
  1625.           if(!cd[found].Displayed)
  1626.             {
  1627.             cd[found].Displayed=TRUE;
  1628.             
  1629.             AddCityEntries(LV_City,cd,cdcount);
  1630.             }
  1631.           
  1632.           get(LV_City,MUIA_List_Entries,&entries);
  1633.           
  1634.           for(i=0;i<entries;i++)
  1635.             {
  1636.             DoMethod(LV_City,MUIM_List_GetEntry,i,&cn);
  1637.             if(cn->cn_CityID==found) temp=i;
  1638.             }
  1639.           
  1640.           nnset(LV_City,MUIA_List_Active,temp);
  1641.           
  1642.           DoMethod(LV_City,MUIM_List_GetEntry,temp,&cn);
  1643.           if(cn)
  1644.             setstring(ST_City,cn->cn_Name);
  1645.           else
  1646.             setstring(ST_City,"");
  1647.           
  1648.           temp=rn->rn_RouteID;
  1649.           
  1650.           AddRouteEntries(LV_Route,rd,rdcount,found);
  1651.           
  1652.           found=temp;
  1653.           temp=MUIV_List_Active_Top;
  1654.           
  1655.           get(LV_Route,MUIA_List_Entries,&entries);
  1656.           
  1657.           for(i=0;i<entries;i++)
  1658.             {
  1659.             DoMethod(LV_Route,MUIM_List_GetEntry,i,&rn);
  1660.             if(rn->rn_RouteID==found) temp=i;
  1661.             }
  1662.           
  1663.           nnset(LV_Route,MUIA_List_Active,temp);
  1664.           
  1665.           set(mainwindow,MUIA_Window_Sleep,FALSE);
  1666.           }
  1667.         break;
  1668.       
  1669.       case LVMOVE:
  1670.         get(LV_Route,MUIA_List_Entries,&entries);
  1671.         DoMethod(LV_Route,MUIM_List_GetEntry,0,&rn);
  1672.         DoMethod(LV_City,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&cn);
  1673.         
  1674.         if(rn && cn)
  1675.           {
  1676.           temp=(rd[rn->rn_RouteID].CityID[1-rd[rn->rn_RouteID].Colm[0]]==cn->cn_CityID);
  1677.           }
  1678.         else temp=FALSE;
  1679.         
  1680.         if(!temp && cn)
  1681.           {
  1682.           setstring(ST_City,cn->cn_Name);
  1683.           AddRouteEntries(LV_Route,rd,rdcount,cn->cn_CityID);
  1684.           }
  1685.         
  1686.         DoMethod(app,MUIM_Application_ReturnID,UPDATEAVAIL);
  1687.         break;
  1688.         
  1689.       case RETURNCITY:
  1690.         // Do search thingy
  1691.         for(i=0;i<cdcount;i++)
  1692.           cd[i].cd_Dummy=cd[i].Displayed;
  1693.         
  1694.         get(ST_City,MUIA_String_Contents,&tmp);
  1695.         strcpy(cbuf,tmp);
  1696.         
  1697.         set(LV_City,MUIA_List_Active,MUIV_List_Active_Off);
  1698.         if(tmp=strchr(cbuf,','))
  1699.           {
  1700.           *tmp++='\0';
  1701.           while(*tmp==' ') tmp++;
  1702.           strcpy(sbuf,tmp);
  1703.           }
  1704.         else strcpy(sbuf,"");
  1705.         
  1706.         SPrintf(compstr,"%s#?,# %s#?",cbuf,sbuf);
  1707.         
  1708.         ParsePatternNoCase(compstr,cbuf,514);
  1709.         
  1710.         get(LV_City,MUIA_List_Entries,&entries);
  1711.         
  1712.         if(Stricmp(compstr,"#?,# #?"))
  1713.           {
  1714.           for(found=0,i=0,exact=FALSE;i<entries;i++)
  1715.             {
  1716.             DoMethod(LV_City,MUIM_List_GetEntry,i,&cn);
  1717.             if(cn)
  1718.               {
  1719.               if(MatchPatternNoCase(cbuf,cn->cn_Name))
  1720.                 {
  1721.                 cd[cn->cn_CityID].Displayed=TRUE;
  1722.                 found++;
  1723.                 choice=i;
  1724.                 
  1725.                 get(ST_City,MUIA_String_Contents,&tmp);
  1726.                 
  1727.                 if(!Stricmp(tmp,cn->cn_Name))
  1728.                   {
  1729.                   temp=i;
  1730.                   exact=TRUE;
  1731.                   }
  1732.                 }
  1733.               else
  1734.                 cd[cn->cn_CityID].Displayed=FALSE;
  1735.               }
  1736.             }
  1737.           }
  1738.         else
  1739.           {
  1740.           for(i=0;i<cdcount;i++)
  1741.             cd[i].Displayed=TRUE;
  1742.           found=2;
  1743.           }
  1744.         
  1745.         if(found==0)
  1746.           {
  1747.           setstring(ST_City,"");
  1748.           MUI_Request(app,mainwindow,0,NULL,"_Ok","No cities matched");
  1749.           set(mainwindow,MUIA_Window_ActiveObject,ST_City);
  1750.           set(LV_City,MUIA_List_Active,MUIV_List_Active_Off);
  1751.           
  1752.           for(i=0;i<cdcount;i++)
  1753.             cd[i].Displayed=cd[i].cd_Dummy;
  1754.           }
  1755.         else if(found==1 || exact)
  1756.           {
  1757.           set(LV_City,MUIA_List_Active,(exact ? temp : choice));
  1758.           if(exact)
  1759.             set(mainwindow,MUIA_Window_ActiveObject,LV_City);
  1760.           else
  1761.             set(mainwindow,MUIA_Window_ActiveObject,ST_City);
  1762.             
  1763.           for(i=0;i<cdcount;i++)
  1764.             cd[i].Displayed=cd[i].cd_Dummy;
  1765.           }
  1766.         else
  1767.           {
  1768.           AddCityEntries(LV_City,cd,cdcount);
  1769.           set(mainwindow,MUIA_Window_ActiveObject,ST_City);
  1770.           DoMethod(app,MUIM_Application_ReturnID,UPDATEAVAIL);
  1771.           }
  1772.         break;
  1773.       
  1774.       case UPDATEAVAIL:
  1775.         get(LV_City,MUIA_List_Active,&i);
  1776.         
  1777.         DisableInactive(BT_AddRoute,i);
  1778.         DisableInactive(BT_RemoveCity,i);
  1779.         DisableInactive(BT_EditCity,i);
  1780.         
  1781.         if(i==MUIV_List_Active_Off)
  1782.           {
  1783.           DoMethod(LV_Route,MUIM_List_Clear,NULL);
  1784.           
  1785.           set(BT_Jump,MUIA_Disabled,TRUE);
  1786.           set(BT_EditRoute,MUIA_Disabled,TRUE);
  1787.           set(BT_RemoveRoute,MUIA_Disabled,TRUE);
  1788.           set(BT_Break,MUIA_Disabled,TRUE);
  1789.           }
  1790.         else
  1791.           {
  1792.           get(LV_Route,MUIA_List_Active,&i);
  1793.           
  1794.           DisableInactive(BT_Jump,i);
  1795.           DisableInactive(BT_EditRoute,i);
  1796.           DisableInactive(BT_RemoveRoute,i);
  1797.           DisableInactive(BT_Break,i);
  1798.           }
  1799.         
  1800.         get(LV_Route,MUIA_List_Entries,&i);
  1801.         set(LV_Route,MUIA_Disabled,(i==0));
  1802.         break;
  1803.       
  1804.       case ALLCITIES:
  1805.         set(mainwindow,MUIA_Window_Sleep,TRUE);
  1806.         
  1807.         for(i=0;i<cdcount;i++)
  1808.           cd[i].Displayed=TRUE;
  1809.         
  1810.         AddCityEntries(LV_City,cd,cdcount);
  1811.         set(mainwindow,MUIA_Window_ActiveObject,ST_City);
  1812.         DoMethod(app,MUIM_Application_ReturnID,UPDATEAVAIL);
  1813.         
  1814.         set(mainwindow,MUIA_Window_Sleep,FALSE);
  1815.         break;
  1816.       }
  1817.     
  1818.     if(going && sigs) sigs=Wait(sigs | SIGBREAKF_CTRL_C);
  1819.     
  1820.     if(sigs & SIGBREAKF_CTRL_C) going=FALSE;
  1821.     }
  1822.   
  1823.   if(reg) free(reg);
  1824.   
  1825.   set(mainwindow,MUIA_Window_Open,FALSE);
  1826.   exit(0);
  1827. }
  1828.  
  1829. void RemoveCity(ULONG citynumber)
  1830. {
  1831.   char tmp;
  1832.   ULONG rnum;
  1833.   
  1834.   for(rnum=0;rnum<rdcount;rnum++)
  1835.     {
  1836.     BOOL thiscity=FALSE;
  1837.     
  1838.     for(tmp=0;tmp<2;tmp++)
  1839.       {
  1840.       if(rd[rnum].CityID[tmp]>citynumber)
  1841.         rd[rnum].CityID[tmp]--;
  1842.       else if(rd[rnum].CityID[tmp]==citynumber)
  1843.         thiscity=TRUE;
  1844.       }
  1845.     
  1846.     if(thiscity)
  1847.       {
  1848.       RemoveRoute(rnum);
  1849.       rnum--;
  1850.       }
  1851.     }
  1852.   
  1853.   for(rnum=0;rnum<cdcount;rnum++)
  1854.     {
  1855.     if(cd[rnum].CityID>citynumber)
  1856.       (cd[rnum].CityID)--;
  1857.     
  1858.     if(&cd[rnum]>&cd[citynumber])
  1859.       memcpy(&cd[rnum-1],&cd[rnum],sizeof(struct CityData));
  1860.     }
  1861.   
  1862.   RedoMemory(cdcount-1,rdcount);
  1863.   cdcount--;
  1864.   
  1865.   ReLink();
  1866. }
  1867.  
  1868. void RemoveRoute(ULONG routenumber)
  1869. {
  1870.   ULONG rnum;
  1871.   
  1872.   for(rnum=0;rnum<rdcount;rnum++)
  1873.     {
  1874.     if(rd[rnum].RouteID>routenumber)
  1875.       (rd[rnum].RouteID)--;
  1876.     
  1877.     if(&rd[rnum]>&rd[routenumber])
  1878.       memcpy(&rd[rnum-1],&rd[rnum],sizeof(struct RouteData));
  1879.     }
  1880.   
  1881.   RedoMemory(cdcount,rdcount-1);
  1882.   rdcount--;
  1883.   
  1884.   ReLink();
  1885. }
  1886.  
  1887. void AddRouteEntries(APTR list,struct RouteData *rd,ULONG rdcount,
  1888.   ULONG citynumber)
  1889. {
  1890.   ULONG i;
  1891.   char tmp;
  1892.   
  1893.   set(list,MUIA_List_Quiet,TRUE);
  1894.   DoMethod(list,MUIM_List_Clear,NULL);
  1895.   
  1896.   for(i=0;i<rdcount;i++)
  1897.     {
  1898.     BOOL found=FALSE;
  1899.     
  1900.     for(tmp=0;tmp<2;tmp++)
  1901.       if(rd[i].CityID[tmp]==citynumber)
  1902.         {
  1903.         found=TRUE;
  1904.         rd[i].Colm[0]=1-tmp;
  1905.         }
  1906.     
  1907.     if(found)
  1908.       DoMethod(list,MUIM_List_InsertSingle,&rd[i],MUIV_List_Insert_Sorted);
  1909.     }
  1910.   
  1911.   set(list,MUIA_List_Quiet,FALSE);
  1912. }
  1913.  
  1914. void SetColumn(struct RouteData *rd,ULONG rdcount,ULONG citynumber)
  1915. {
  1916.   ULONG i;
  1917.   char tmp;
  1918.   
  1919.   for(i=0;i<rdcount;i++)
  1920.     {
  1921.     for(tmp=0;tmp<2;tmp++)
  1922.       if(rd[i].CityID[tmp]==citynumber)
  1923.         {
  1924.         rd[i].Colm[0]=1-tmp;
  1925.         }
  1926.     }
  1927. }
  1928.  
  1929. APTR DLabel(const char *string);
  1930.  
  1931. APTR DLabel(const char *string)
  1932. {
  1933.   APTR tmp;
  1934.   
  1935.   tmp=TextObject,
  1936.            StringFrame,
  1937.            MUIA_FramePhantomHoriz, TRUE,
  1938.            MUIA_Text_SetMin,   FALSE,
  1939.            MUIA_Text_SetMax,   FALSE,
  1940.            MUIA_FixWidthTxt,   "km/h",
  1941.            MUIA_Text_PreParse, MUIX_L,
  1942.            MUIA_Text_Contents, string,
  1943.            MUIA_InputMode,     MUIV_InputMode_None,
  1944.            End;
  1945.   
  1946.   return tmp;
  1947. }
  1948.  
  1949. #define ER_FROM        (200L)
  1950. #define ER_TO        (201L)
  1951. #define ER_SPEED    (202L)
  1952. #define ER_MEASUREUNITS    (203L)
  1953. #define ER_OK        (204L)
  1954. #define ER_CANCEL    (205L)
  1955. #define ER_DISTANCE    (206L)
  1956.  
  1957. char *unitlabels[]={ "Metric", "English", NULL };
  1958.  
  1959. char *distlabels[]={ "km", "mi", NULL };
  1960.  
  1961. char *speedlabels[]={ "km/h", "mph", "min", NULL };
  1962.  
  1963. char *rteclasses[]={
  1964.   "Other (speed)",
  1965.   "Other (time)",
  1966.   "Rural Interstate",
  1967.   "Suburban Interstate",
  1968.   "Urban Interstate",
  1969.   "Rural Highway (4 Lane)",
  1970.   "Rural Highway (2 Lane)",
  1971.   "Suburban Highway",
  1972.   "Suburban Road",
  1973.   "Urban Road",
  1974.   "Rural Interstate (55)",
  1975.   "Metro Interstate",
  1976.   "Autoroute (Canada)",
  1977.   "Main Highway (Canada)",
  1978.   "Rural Motorway (UK)",
  1979.   "Suburban Motorway (UK)",
  1980.   "Urban Motorway (UK)",
  1981.   "Primary 4 Lane (UK)",
  1982.   "Primary 2 Lane (UK)",
  1983.   "Other Route (UK)",
  1984.   NULL};
  1985.  
  1986. ULONG EditRoute(ULONG RouteNumber, ULONG OriginCity, char *tbar)
  1987. // Edit route segments
  1988. //
  1989. // Retval: -1 = cancel; -2 = ok; -3 = quit received;
  1990. {
  1991.   ULONG retval=(ULONG)-1, i, sigs, tmp, tmp2;
  1992.   APTR editwindow, BT_From, BT_To, ST_Distance, CY_Speed, ST_Speed;
  1993.   APTR BT_Ok, BT_Cancel, CY_MeasureUnits, ST_Hiway;
  1994.   APTR TX_From, TX_To, TX_DistUnits, TX_SpeedUnits, ST_FromExit, ST_ToExit;
  1995.   BOOL going=TRUE;
  1996.   UWORD fromcity, tocity;
  1997.   char fside, tside, *str;
  1998.   
  1999.   static char tbuf[256];
  2000.   
  2001.   editwindow=WindowObject,
  2002.                MUIA_Window_Title,       tbar,
  2003.                MUIA_Window_ScreenTitle, COPYRIGHT,
  2004.                MUIA_Window_ID,          200,
  2005.                MUIA_Window_NoMenus,     TRUE,
  2006.                MUIA_HelpNode,           "EditRoute",
  2007.                
  2008.                WindowContents,
  2009.                VGroup,
  2010.                  Child,VGroup,
  2011.                    GroupFrameT("Route"),
  2012.                    Child,ColGroup(4),
  2013.                      Child, BT_From=KeyButton("From...",'f'),
  2014.                      Child, TX_From=SimpleText(""),
  2015.                      Child, Label2("Exit:"),
  2016.                      Child, ST_FromExit=String("",6),
  2017.                      Child, BT_To=KeyButton("To...",'t'),
  2018.                      Child, TX_To=SimpleText(""),
  2019.                      Child, Label2("Exit:"),
  2020.                      Child, ST_ToExit=String("",6),
  2021.                      End,
  2022.                    Child, MUI_MakeObject(MUIO_HBar,0),
  2023.                    Child, ColGroup(3),
  2024.                      Child, KeyLabel2("Name:",'n'),
  2025.                      Child, ST_Hiway=KeyString("",32,'n'),
  2026.                      Child, HSpace(0),
  2027.                      Child, KeyLabel2("Units:",'u'),
  2028.                      Child, CY_MeasureUnits=KeyCycle(unitlabels,'u'),
  2029.                      Child, HSpace(0),
  2030.                      Child, KeyLabel2("Distance:",'d'),
  2031.                      Child, ST_Distance=StringObject,
  2032.                        StringFrame,
  2033.                        MUIA_String_Accept, "0123456789",
  2034.                        MUIA_String_Format, MUIV_String_Format_Right,
  2035.                        MUIA_String_MaxLen, 5,
  2036.                        MUIA_ControlChar, 'd',
  2037.                        End,
  2038.                      Child, TX_DistUnits=DLabel(""),
  2039.                      Child, KeyLabel2("Grade:",'g'),
  2040.                      Child, CY_Speed=KeyCycle(rteclasses,'g'),
  2041.                      Child, HSpace(0),
  2042.                      Child, HSpace(0),
  2043.                      Child,ST_Speed=StringObject,
  2044.                        StringFrame,
  2045.                        MUIA_String_Accept, "0123456789",
  2046.                        MUIA_String_Format, MUIV_String_Format_Right,
  2047.                        MUIA_String_MaxLen, 5,
  2048.                        End,
  2049.                      Child, TX_SpeedUnits=DLabel(""),
  2050.                      End,
  2051.                    End,
  2052.                  Child, HGroup,
  2053.                    Child, BT_Ok=KeyButton("Ok",'o'),
  2054.                    Child, BT_Cancel=KeyButton("Cancel",'c'),
  2055.                    MUIA_Group_SameWidth, TRUE,
  2056.                    End,
  2057.                  End,
  2058.                End;
  2059.   
  2060.   if(editwindow)
  2061.     {
  2062.     set(app,MUIA_Application_Sleep,TRUE);
  2063.     
  2064.     DoMethod(app,OM_ADDMEMBER,editwindow);
  2065.     
  2066.     DoMethod(editwindow,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
  2067.       app,2,MUIM_Application_ReturnID,ER_CANCEL);
  2068.     
  2069.     ButtonBehave(BT_To, ER_TO);
  2070.     ButtonBehave(BT_From, ER_FROM);
  2071.     ButtonBehave(BT_Ok, ER_OK);
  2072.     ButtonBehave(BT_Cancel, ER_CANCEL);
  2073.     
  2074.     CycleBehave(CY_Speed, ER_SPEED);
  2075.     CycleBehave(CY_MeasureUnits, ER_MEASUREUNITS);
  2076.     
  2077.     setcycle(CY_MeasureUnits, rd[RouteNumber].Units);
  2078.     setcycle(CY_Speed, rd[RouteNumber].SpeedCode);
  2079.     
  2080.     setstring(ST_Hiway, rd[RouteNumber].Hiway);
  2081.     
  2082.     set(ST_Distance,MUIA_String_Integer,rd[RouteNumber].Distance);
  2083.     
  2084.     if(rd[RouteNumber].SpeedCode<2)
  2085.       {
  2086.       set(ST_Speed,MUIA_String_Integer,rd[RouteNumber].Speed);
  2087.       }
  2088.     else
  2089.       {
  2090.       set(ST_Speed,MUIA_Disabled,TRUE);
  2091.       }
  2092.     
  2093.     if(rd[RouteNumber].SpeedCode==USE_TIME)
  2094.       {
  2095.       settext(TX_SpeedUnits, speedlabels[2]);
  2096.       }
  2097.     else
  2098.       {
  2099.       settext(TX_SpeedUnits, speedlabels[rd[RouteNumber].Units]);
  2100.       }
  2101.     
  2102.     tside=rd[RouteNumber].Colm[0];
  2103.     fside=1-tside;
  2104.     
  2105.     fromcity=rd[RouteNumber].CityID[fside];
  2106.     tocity=rd[RouteNumber].CityID[tside];
  2107.     
  2108.     if(fromcity!=(UWORD)-1)
  2109.       {
  2110.       SPrintf(tbuf,"%s, %s",cd[fromcity].CityName,cd[fromcity].StateName);
  2111.       settext(TX_From,tbuf);
  2112.       
  2113.       setstring(ST_FromExit,rd[RouteNumber].Exits[fside]);
  2114.       }
  2115.     
  2116.     if(tocity!=(UWORD)-1)
  2117.       {
  2118.       SPrintf(tbuf,"%s, %s",cd[tocity].CityName,cd[tocity].StateName);
  2119.       settext(TX_To,tbuf);
  2120.       
  2121.       setstring(ST_ToExit,rd[RouteNumber].Exits[tside]);
  2122.       }
  2123.     
  2124.     set(BT_Ok,MUIA_Disabled,(fromcity==(UWORD)-1 || tocity==(UWORD)-1));
  2125.     
  2126.     settext(TX_DistUnits, distlabels[rd[RouteNumber].Units]);
  2127.     
  2128.     DoMethod(editwindow,MUIM_Window_SetCycleChain,ST_Hiway,
  2129.       CY_MeasureUnits,ST_Distance,CY_Speed,ST_Speed,ST_FromExit,ST_ToExit,
  2130.       NULL);
  2131.     
  2132.     MeasureUnits=rd[RouteNumber].Units;
  2133.     
  2134.     set(editwindow,MUIA_Window_Open,TRUE);
  2135.     get(editwindow,MUIA_Window_Open,&i);
  2136.     if(i)
  2137.       {
  2138.       set(editwindow,MUIA_Window_ActiveObject,ST_Hiway);
  2139.       
  2140.       while(going)
  2141.         {
  2142.         switch(DoMethod(app,MUIM_Application_Input,&sigs))
  2143.           { // Can't ignore MUIV_Application_ReturnID_Quit
  2144.           case MUIV_Application_ReturnID_Quit:
  2145.             retval=(ULONG)-3;
  2146.             going=FALSE;
  2147.             break;
  2148.           
  2149.           case ER_CANCEL:
  2150.             retval=(ULONG)-1;
  2151.             going=FALSE;
  2152.             break;
  2153.           
  2154.           case ER_OK:
  2155.             // Some stuff here
  2156.             get(ST_Speed,MUIA_String_Integer,&tmp);
  2157.             get(ST_Distance,MUIA_String_Integer,&tmp2);
  2158.             get(CY_Speed,MUIA_Cycle_Active,&i);
  2159.             
  2160.             if((i>USE_TIME || tmp) && tmp2)
  2161.               {
  2162.               rd[RouteNumber].SpeedCode=i;
  2163.               
  2164.               if(i<=USE_TIME)
  2165.                 {
  2166.                 rd[RouteNumber].Speed=tmp;
  2167.                 }
  2168.               else
  2169.                 rd[RouteNumber].Speed=0;
  2170.               
  2171.               rd[RouteNumber].CityID[fside]=fromcity;
  2172.               rd[RouteNumber].CityID[tside]=tocity;
  2173.               
  2174.               rd[RouteNumber].Distance=tmp2;
  2175.               
  2176.               get(ST_Hiway,MUIA_String_Contents,&str);
  2177.               strcpy(rd[RouteNumber].Hiway,str);
  2178.               
  2179.               get(ST_FromExit,MUIA_String_Contents,&str);
  2180.               strcpy(rd[RouteNumber].Exits[fside],str);
  2181.               
  2182.               get(ST_ToExit,MUIA_String_Contents,&str);
  2183.               strcpy(rd[RouteNumber].Exits[tside],str);
  2184.               
  2185.               get(CY_MeasureUnits,MUIA_Cycle_Active,&i);
  2186.               rd[RouteNumber].Units=i;
  2187.               
  2188.               retval=(ULONG)-2;
  2189.               going=FALSE;
  2190.               }
  2191.             else if(tmp2)
  2192.               MUI_Request(app,editwindow,0,NULL,"_Ok",
  2193.                 "You must enter a speed or time.");
  2194.             else
  2195.               MUI_Request(app,editwindow,0,NULL,"_Ok",
  2196.                 "You must enter a distance.");
  2197.             break;
  2198.           
  2199.           case ER_FROM:
  2200.             i=ChooseCity(cd,cdcount,fromcity,"Choose `from' city...");
  2201.             if(i==(ULONG)-2)
  2202.               {
  2203.               retval=(ULONG)-3;
  2204.               going=FALSE;
  2205.               }
  2206.             else if(i!=(ULONG)-1 && i==tocity)
  2207.               {
  2208.               MUI_Request(app,editwindow,0,NULL,"_Ok",
  2209.                 "Can't make `from' city same as `to' city.");
  2210.               }
  2211.             else if(i!=(ULONG)-1)
  2212.               {
  2213.               fromcity=i;
  2214.               
  2215.               SPrintf(tbuf,"%s, %s",cd[fromcity].CityName,
  2216.                 cd[fromcity].StateName);
  2217.               settext(TX_From,tbuf);
  2218.               
  2219.               set(BT_Ok,MUIA_Disabled,
  2220.                 (fromcity==(UWORD)-1 || tocity==(UWORD)-1));
  2221.               }
  2222.             break;
  2223.             
  2224.           case ER_TO:
  2225.             i=ChooseCity(cd,cdcount,tocity,"Choose `to' city...");
  2226.             if(i==(ULONG)-2)
  2227.               {
  2228.               retval=(ULONG)-3;
  2229.               going=FALSE;
  2230.               }
  2231.             else if(i!=(ULONG)-1 && i==fromcity)
  2232.               {
  2233.               MUI_Request(app,editwindow,0,NULL,"_Ok",
  2234.                 "Can't make `to' city same as `from' city.");
  2235.               }
  2236.             else if(i!=(ULONG)-1)
  2237.               {
  2238.               tocity=i;
  2239.               
  2240.               SPrintf(tbuf,"%s, %s",cd[tocity].CityName,
  2241.                 cd[tocity].StateName);
  2242.               settext(TX_To,tbuf);
  2243.               
  2244.               set(BT_Ok,MUIA_Disabled,
  2245.                 (fromcity==(UWORD)-1 || tocity==(UWORD)-1));
  2246.               }
  2247.             break;
  2248.           
  2249.           case ER_SPEED:
  2250.             get(CY_MeasureUnits,MUIA_Cycle_Active,&i);
  2251.             get(CY_Speed, MUIA_Cycle_Active, &tmp);
  2252.             
  2253.             set(ST_Speed, MUIA_Disabled, (tmp>USE_TIME));
  2254.             
  2255.             if(tmp==USE_TIME)
  2256.               settext(TX_SpeedUnits, speedlabels[2]);
  2257.             else
  2258.               settext(TX_SpeedUnits, speedlabels[i]);
  2259.             break;
  2260.           
  2261.           case ER_MEASUREUNITS:
  2262.             get(CY_MeasureUnits,MUIA_Cycle_Active,&i);
  2263.             get(CY_Speed, MUIA_Cycle_Active, &tmp);
  2264.             
  2265.             settext(TX_DistUnits, distlabels[i]);
  2266.             
  2267.             if(tmp==USE_TIME)
  2268.               settext(TX_SpeedUnits, speedlabels[2]);
  2269.             else
  2270.               settext(TX_SpeedUnits, speedlabels[i]);
  2271.             
  2272.             if(i!=MeasureUnits)
  2273.               {
  2274.               ULONG tval;
  2275.               
  2276.               get(ST_Distance, MUIA_String_Integer, &tval);
  2277.               
  2278.               tval=ConvertDist(tval,MeasureUnits,i);
  2279.               
  2280.               set(ST_Distance, MUIA_String_Integer, tval);
  2281.               
  2282.               if(tmp!=USE_TIME)
  2283.                 {
  2284.                 get(ST_Speed, MUIA_String_Integer, &tval);
  2285.                 
  2286.                 tval=ConvertDist(tval,MeasureUnits,i);
  2287.                 
  2288.                 set(ST_Speed, MUIA_String_Integer, tval);
  2289.                 }
  2290.               
  2291.               MeasureUnits=i;
  2292.               }
  2293.             break;
  2294.           }
  2295.         
  2296.         if(going && sigs) Wait(sigs);
  2297.         }
  2298.       }
  2299.     else
  2300.       MUI_Request(app,mainwindow,0,NULL,"_Ok","Couldn't open edit window.");
  2301.     
  2302.     set(editwindow,MUIA_Window_Open,FALSE);
  2303.     DoMethod(app,OM_REMMEMBER,editwindow);
  2304.     MUI_DisposeObject(editwindow);
  2305.     
  2306.     set(app,MUIA_Application_Sleep,FALSE);
  2307.     }
  2308.   else
  2309.     MUI_Request(app,mainwindow,0,NULL,"_Ok","Couldn't create edit window.");
  2310.   
  2311.   return retval;
  2312. }
  2313.  
  2314. #define BR_FROM        (300L)
  2315. #define BR_TO        (301L)
  2316. #define BR_VIA        (302L)
  2317. #define BR_MEASUREUNITS    (303L)
  2318. #define BR_OK        (304L)
  2319. #define BR_CANCEL    (305L)
  2320.  
  2321. #define BR_SPEED1    (306L)
  2322. #define BR_SPEED2    (307L)
  2323. #define BR_DIST1    (308L)
  2324. #define BR_DIST2    (309L)
  2325.  
  2326. ULONG BreakRoute(ULONG rte, ULONG origin)
  2327. // Break route segments
  2328. //
  2329. // Retval: -1 = cancel; -2 = ok; -3 = quit received;
  2330. {
  2331.   ULONG retval=(ULONG)-1, i, i2, sigs, tmp, tmp2;
  2332.   UWORD distance, fromcity, tocity, viacity;
  2333.   APTR editwindow, BT_From, BT_To, ST_Distance1, CY_Speed1, ST_Speed1;
  2334.   APTR BT_Ok, BT_Cancel, CY_MeasureUnits, ST_Hiway, BT_BreakPoint;
  2335.   APTR TX_BreakPoint, ST_BreakExit;
  2336.   APTR TX_From, TX_To, TX_Dist1Units, TX_Speed1Units, ST_FromExit, ST_ToExit;
  2337.   APTR ST_Distance2, CY_Speed2, ST_Speed2, TX_Dist2Units, TX_Speed2Units;
  2338.   APTR CB_Lock1, CB_Lock2;
  2339.   BOOL going=TRUE;
  2340.   char fside, tside, *str;
  2341.   
  2342.   static char tbuf[256];
  2343.   
  2344.   if(!RedoMemory(cdcount,rdcount+1))
  2345.     {
  2346.     MUI_Request(app,mainwindow,0,NULL,"_Ok","Couldn't open breakpoint window.");
  2347.     return retval;
  2348.     }
  2349.   
  2350.   viacity=(UWORD)-1;
  2351.   
  2352.   editwindow=WindowObject,
  2353.                MUIA_Window_Title,       "Break route segment",
  2354.                MUIA_Window_ScreenTitle, COPYRIGHT,
  2355.                MUIA_Window_ID,          300,
  2356.                MUIA_Window_NoMenus,     TRUE,
  2357.                MUIA_HelpNode,           "BreakRoute",
  2358.                
  2359.                WindowContents,
  2360.                VGroup,
  2361.                  Child,VGroup,
  2362.                    Child,ColGroup(4),
  2363.                      Child, BT_From=KeyButton("From...",'f'),
  2364.                      Child, TX_From=SimpleText(""),
  2365.                      Child, Label2("Exit:"),
  2366.                      Child, ST_FromExit=String("",6),
  2367.                      Child, BT_BreakPoint=KeyButton("Via...",'v'),
  2368.                      Child, TX_BreakPoint=SimpleText(""),
  2369.                      Child, Label2("Exit:"),
  2370.                      Child, ST_BreakExit=String("",6),
  2371.                      Child, BT_To=KeyButton("To...",'t'),
  2372.                      Child, TX_To=SimpleText(""),
  2373.                      Child, Label2("Exit:"),
  2374.                      Child, ST_ToExit=String("",6),
  2375.                      End,
  2376.                    Child, MUI_MakeObject(MUIO_HBar,0),
  2377.                    Child, ColGroup(2),
  2378.                      Child, KeyLabel2("Name:",'n'),
  2379.                      Child, ST_Hiway=KeyString("",32,'n'),
  2380.                      Child, KeyLabel2("Units:",'u'),
  2381.                      Child, CY_MeasureUnits=KeyCycle(unitlabels,'u'),
  2382.                      End,
  2383.                    Child, HGroup,
  2384.                      Child, ColGroup(3),
  2385.                        GroupFrameT("`From' to midpoint"),
  2386.                        Child, KeyLabel2("Distance:",'d'),
  2387.                        Child, HGroup,
  2388.                          Child, CB_Lock1=CheckMark(TRUE),
  2389.                          Child, LLabel1("Link"),
  2390.                          Child, ST_Distance1=StringObject,
  2391.                            StringFrame,
  2392.                            MUIA_String_Accept, "0123456789",
  2393.                            MUIA_String_Format, MUIV_String_Format_Right,
  2394.                            MUIA_String_MaxLen, 5,
  2395.                            MUIA_ControlChar, 'd',
  2396.                            End,
  2397.                          End,
  2398.                        Child, TX_Dist1Units=DLabel(""),
  2399.                        Child, KeyLabel2("Grade:",'g'),
  2400.                        Child, CY_Speed1=KeyCycle(rteclasses,'g'),
  2401.                        Child, HSpace(0),
  2402.                        Child, HSpace(0),
  2403.                        Child,ST_Speed1=StringObject,
  2404.                          StringFrame,
  2405.                          MUIA_String_Accept, "0123456789",
  2406.                          MUIA_String_Format, MUIV_String_Format_Right,
  2407.                          MUIA_String_MaxLen, 5,
  2408.                          End,
  2409.                        Child, TX_Speed1Units=DLabel(""),
  2410.                        End,
  2411.                      Child, ColGroup(3),
  2412.                        GroupFrameT("`To' to midpoint"),
  2413.                        Child, Label2("Distance:"),
  2414.                        Child, HGroup,
  2415.                          Child, CB_Lock2=CheckMark(TRUE),
  2416.                          Child, LLabel1("Link"),
  2417.                          Child, ST_Distance2=StringObject,
  2418.                            StringFrame,
  2419.                            MUIA_String_Accept, "0123456789",
  2420.                            MUIA_String_Format, MUIV_String_Format_Right,
  2421.                            MUIA_String_MaxLen, 5,
  2422.                            End,
  2423.                          End,
  2424.                        Child, TX_Dist2Units=DLabel(""),
  2425.                        Child, Label2("Grade:"),
  2426.                        Child, CY_Speed2=Cycle(rteclasses),
  2427.                        Child, HSpace(0),
  2428.                        Child, HSpace(0),
  2429.                        Child,ST_Speed2=StringObject,
  2430.                          StringFrame,
  2431.                          MUIA_String_Accept, "0123456789",
  2432.                          MUIA_String_Format, MUIV_String_Format_Right,
  2433.                          MUIA_String_MaxLen, 5,
  2434.                          End,
  2435.                        Child, TX_Speed2Units=DLabel(""),
  2436.                        End,
  2437.                      End,
  2438.                    End,
  2439.                  Child, HGroup,
  2440.                    Child, BT_Ok=KeyButton("Ok",'o'),
  2441.                    Child, BT_Cancel=KeyButton("Cancel",'c'),
  2442.                    MUIA_Group_SameWidth, TRUE,
  2443.                    End,
  2444.                  End,
  2445.                End;
  2446.   
  2447.   if(editwindow)
  2448.     {
  2449.     set(app,MUIA_Application_Sleep,TRUE);
  2450.     
  2451.     DoMethod(app,OM_ADDMEMBER,editwindow);
  2452.     
  2453.     DoMethod(editwindow,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
  2454.       app,2,MUIM_Application_ReturnID,BR_CANCEL);
  2455.     
  2456.     DoMethod(CY_Speed1,MUIM_Notify,MUIA_Cycle_Active,MUIV_EveryTime,
  2457.       CY_Speed2,3,MUIM_Set,MUIA_Cycle_Active,MUIV_TriggerValue);
  2458.     
  2459.     DoMethod(ST_Speed1,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,
  2460.       ST_Speed2,3,MUIM_Set,MUIA_String_Contents,MUIV_TriggerValue);
  2461.     
  2462.     ButtonBehave(BT_To, BR_TO);
  2463.     ButtonBehave(BT_From, BR_FROM);
  2464.     ButtonBehave(BT_BreakPoint, BR_VIA);
  2465.     ButtonBehave(BT_Ok, BR_OK);
  2466.     ButtonBehave(BT_Cancel, BR_CANCEL);
  2467.     
  2468.     CycleBehave(CY_Speed1, BR_SPEED1);
  2469.     CycleBehave(CY_Speed2, BR_SPEED2);
  2470.     CycleBehave(CY_MeasureUnits, BR_MEASUREUNITS);
  2471.     
  2472.     StringBehave(ST_Distance1, BR_DIST1);
  2473.     StringBehave(ST_Distance2, BR_DIST2);
  2474.     
  2475.     setcycle(CY_MeasureUnits, rd[rte].Units);
  2476.     setcycle(CY_Speed1, rd[rte].SpeedCode);
  2477.     
  2478.     setstring(ST_Hiway, rd[rte].Hiway);
  2479.     
  2480.     distance=rd[rte].Distance;
  2481.     
  2482.     if(rd[rte].SpeedCode<2)
  2483.       {
  2484.       set(ST_Speed1,MUIA_String_Integer,rd[rte].Speed);
  2485.       }
  2486.     else
  2487.       {
  2488.       set(ST_Speed1,MUIA_Disabled,TRUE);
  2489.       set(ST_Speed2,MUIA_Disabled,TRUE);
  2490.       }
  2491.     
  2492.     if(rd[rte].SpeedCode==USE_TIME)
  2493.       {
  2494.       settext(TX_Speed1Units, speedlabels[2]);
  2495.       }
  2496.     else
  2497.       {
  2498.       settext(TX_Speed1Units, speedlabels[rd[rte].Units]);
  2499.       }
  2500.     
  2501.     tside=rd[rte].Colm[0];
  2502.     fside=1-tside;
  2503.     
  2504.     fromcity=rd[rte].CityID[fside];
  2505.     tocity=rd[rte].CityID[tside];
  2506.     
  2507.     SPrintf(tbuf,"%s, %s",cd[fromcity].CityName,cd[fromcity].StateName);
  2508.     settext(TX_From,tbuf);
  2509.     
  2510.     setstring(ST_FromExit,rd[rte].Exits[fside]);
  2511.     
  2512.     SPrintf(tbuf,"%s, %s",cd[tocity].CityName,cd[tocity].StateName);
  2513.     settext(TX_To,tbuf);
  2514.     
  2515.     setstring(ST_ToExit,rd[rte].Exits[tside]);
  2516.     
  2517.     set(BT_Ok,MUIA_Disabled,TRUE);
  2518.     
  2519.     settext(TX_Dist1Units, distlabels[rd[rte].Units]);
  2520.     settext(TX_Dist2Units, distlabels[rd[rte].Units]);
  2521.     
  2522.     DoMethod(editwindow,MUIM_Window_SetCycleChain,ST_Hiway,
  2523.       CY_MeasureUnits,CB_Lock1,ST_Distance1,CY_Speed1,ST_Speed1,
  2524.       CB_Lock2,ST_Distance2,CY_Speed2,ST_Speed2,ST_FromExit,
  2525.       ST_BreakExit,ST_ToExit,NULL);
  2526.     
  2527.     MeasureUnits=rd[rte].Units;
  2528.     
  2529.     set(editwindow,MUIA_Window_Open,TRUE);
  2530.     get(editwindow,MUIA_Window_Open,&i);
  2531.     if(i)
  2532.       {
  2533.       set(editwindow,MUIA_Window_ActiveObject,ST_Hiway);
  2534.       
  2535.       while(going)
  2536.         {
  2537.         switch(DoMethod(app,MUIM_Application_Input,&sigs))
  2538.           { // Can't ignore MUIV_Application_ReturnID_Quit
  2539.           case MUIV_Application_ReturnID_Quit:
  2540.             retval=(ULONG)-3;
  2541.             going=FALSE;
  2542.             RedoMemory(cdcount,rdcount);
  2543.             break;
  2544.           
  2545.           case BR_CANCEL:
  2546.             retval=(ULONG)-1;
  2547.             going=FALSE;
  2548.             RedoMemory(cdcount,rdcount);
  2549.             break;
  2550.           
  2551.           case BR_OK:
  2552.             // Some stuff here
  2553.             get(CY_Speed1,MUIA_Cycle_Active,&i);
  2554.             get(ST_Speed1,MUIA_String_Integer,&tmp);
  2555.             
  2556.             get(CY_Speed2,MUIA_Cycle_Active,&i2);
  2557.             get(ST_Speed2,MUIA_String_Integer,&tmp2);
  2558.             
  2559.             if((i>USE_TIME || tmp) && (i2>USE_TIME || tmp2))
  2560.               {
  2561.               rd[rte].SpeedCode=i;
  2562.               
  2563.               if(i<=USE_TIME)
  2564.                 {
  2565.                 rd[rte].Speed=tmp;
  2566.                 }
  2567.               else
  2568.                 rd[rte].Speed=0;
  2569.               
  2570.               rd[rdcount].SpeedCode=i2;
  2571.               
  2572.               if(i<=USE_TIME)
  2573.                 {
  2574.                 rd[rdcount].Speed=tmp2;
  2575.                 }
  2576.               else
  2577.                 rd[rdcount].Speed=0;
  2578.               
  2579.               rd[rdcount].RouteID=rdcount;
  2580.               
  2581.               rd[rte].CityID[fside]=fromcity;
  2582.               rd[rte].CityID[tside]=viacity;
  2583.               rd[rdcount].CityID[0]=viacity;
  2584.               rd[rdcount].CityID[1]=tocity;
  2585.               
  2586.               get(ST_Distance1,MUIA_String_Integer,&i);
  2587.               rd[rte].Distance=i;
  2588.               
  2589.               get(ST_Distance2,MUIA_String_Integer,&i);
  2590.               rd[rdcount].Distance=i;
  2591.               
  2592.               get(CY_Speed2,MUIA_Cycle_Active,&i);
  2593.               rd[rdcount].SpeedCode=i;
  2594.               
  2595.               get(ST_Hiway,MUIA_String_Contents,&str);
  2596.               strcpy(rd[rte].Hiway,str);
  2597.               strcpy(rd[rdcount].Hiway,str);
  2598.               
  2599.               get(ST_FromExit,MUIA_String_Contents,&str);
  2600.               strcpy(rd[rte].Exits[fside],str);
  2601.               
  2602.               get(ST_BreakExit,MUIA_String_Contents,&str);
  2603.               strcpy(rd[rte].Exits[tside],str);
  2604.               strcpy(rd[rdcount].Exits[0],str);
  2605.               
  2606.               get(ST_ToExit,MUIA_String_Contents,&str);
  2607.               strcpy(rd[rdcount].Exits[1],str);
  2608.               
  2609.               get(CY_MeasureUnits,MUIA_Cycle_Active,&i);
  2610.               rd[rte].Units=i;
  2611.               rd[rdcount].Units=i;
  2612.               
  2613.               retval=(ULONG)-2;
  2614.               going=FALSE;
  2615.               rdcount++;
  2616.               }
  2617.             else
  2618.               MUI_Request(app,editwindow,0,NULL,"_Ok",
  2619.                 "You must specify speeds or times.");
  2620.             break;
  2621.           
  2622.           case BR_FROM:
  2623.             i=ChooseCity(cd,cdcount,fromcity,"Choose `from' city...");
  2624.             if(i==(ULONG)-2)
  2625.               {
  2626.               retval=(ULONG)-3;
  2627.               going=FALSE;
  2628.               }
  2629.             else if(i!=(ULONG)-1 && (i==tocity || i==viacity))
  2630.               {
  2631.               MUI_Request(app,editwindow,0,NULL,"_Ok",
  2632.                 "Can't make `from' city same\nas `to' or `via' city.");
  2633.               }
  2634.             else if(i!=(ULONG)-1)
  2635.               {
  2636.               fromcity=i;
  2637.               
  2638.               SPrintf(tbuf,"%s, %s",cd[fromcity].CityName,
  2639.                 cd[fromcity].StateName);
  2640.               settext(TX_From,tbuf);
  2641.               
  2642.               get(ST_Distance1,MUIA_String_Integer,&tmp);
  2643.               get(ST_Distance2,MUIA_String_Integer,&tmp2);
  2644.               set(BT_Ok,MUIA_Disabled,
  2645.                 (fromcity==(UWORD)-1 || tocity==(UWORD)-1 ||
  2646.                 viacity==(UWORD)-1 || !tmp || !tmp2));
  2647.               }
  2648.             break;
  2649.             
  2650.           case BR_TO:
  2651.             i=ChooseCity(cd,cdcount,tocity,"Choose `to' city...");
  2652.             if(i==(ULONG)-2)
  2653.               {
  2654.               retval=(ULONG)-3;
  2655.               going=FALSE;
  2656.               }
  2657.             else if(i!=(ULONG)-1 && (i==fromcity || i==viacity))
  2658.               {
  2659.               MUI_Request(app,editwindow,0,NULL,"_Ok",
  2660.                 "Can't make `to' city same\nas `from' or `via' city.");
  2661.               }
  2662.             else if(i!=(ULONG)-1)
  2663.               {
  2664.               tocity=i;
  2665.               
  2666.               SPrintf(tbuf,"%s, %s",cd[tocity].CityName,
  2667.                 cd[tocity].StateName);
  2668.               settext(TX_To,tbuf);
  2669.               
  2670.               get(ST_Distance1,MUIA_String_Integer,&tmp);
  2671.               get(ST_Distance2,MUIA_String_Integer,&tmp2);
  2672.               set(BT_Ok,MUIA_Disabled,
  2673.                 (fromcity==(UWORD)-1 || tocity==(UWORD)-1 ||
  2674.                 viacity==(UWORD)-1 || !tmp || !tmp2));
  2675.               }
  2676.             break;
  2677.           
  2678.           case BR_VIA:
  2679.             i=ChooseCity(cd,cdcount,viacity,"Choose breakpoint...");
  2680.             if(i==(ULONG)-2)
  2681.               {
  2682.               retval=(ULONG)-3;
  2683.               going=FALSE;
  2684.               }
  2685.             else if(i!=(ULONG)-1 && (i==tocity || i==fromcity))
  2686.               {
  2687.               MUI_Request(app,editwindow,0,NULL,"_Ok",
  2688.                 "Can't make `via' city same\nas `to' or `from' city.");
  2689.               }
  2690.             else if(i!=(ULONG)-1)
  2691.               {
  2692.               viacity=i;
  2693.               
  2694.               SPrintf(tbuf,"%s, %s",cd[viacity].CityName,
  2695.                 cd[viacity].StateName);
  2696.               settext(TX_BreakPoint,tbuf);
  2697.               
  2698.               get(ST_Distance1,MUIA_String_Integer,&tmp);
  2699.               get(ST_Distance2,MUIA_String_Integer,&tmp2);
  2700.               set(BT_Ok,MUIA_Disabled,
  2701.                 (fromcity==(UWORD)-1 || tocity==(UWORD)-1 ||
  2702.                 viacity==(UWORD)-1 || !tmp || !tmp2));
  2703.               }
  2704.             break;
  2705.           
  2706.           case BR_SPEED1:
  2707.             get(CY_MeasureUnits,MUIA_Cycle_Active,&i);
  2708.             get(CY_Speed1, MUIA_Cycle_Active, &tmp);
  2709.             
  2710.             set(ST_Speed1, MUIA_Disabled, (tmp>USE_TIME));
  2711.             
  2712.             if(tmp==USE_TIME)
  2713.               settext(TX_Speed1Units, speedlabels[2]);
  2714.             else
  2715.               settext(TX_Speed1Units, speedlabels[i]);
  2716.               
  2717.             break;
  2718.           
  2719.           case BR_SPEED2:
  2720.             get(CY_MeasureUnits,MUIA_Cycle_Active,&i);
  2721.             get(CY_Speed2, MUIA_Cycle_Active, &tmp);
  2722.             
  2723.             set(ST_Speed2, MUIA_Disabled, (tmp>USE_TIME));
  2724.             
  2725.             if(tmp==USE_TIME)
  2726.               settext(TX_Speed2Units, speedlabels[2]);
  2727.             else
  2728.               settext(TX_Speed2Units, speedlabels[i]);
  2729.               
  2730.             break;
  2731.           
  2732.           case BR_DIST1:
  2733.             get(CB_Lock1,MUIA_Selected,&i);
  2734.             if(i)
  2735.               {
  2736.               get(ST_Distance1,MUIA_String_Integer,&i);
  2737.               tmp=ConvertDist(distance,rd[rte].Units,MeasureUnits);
  2738.               i=(i>tmp ? tmp : i);
  2739.               set(ST_Distance1,MUIA_String_Integer,i);
  2740.               set(ST_Distance2,MUIA_String_Integer,tmp-i);
  2741.               }
  2742.             
  2743.             get(ST_Distance1,MUIA_String_Integer,&tmp);
  2744.             get(ST_Distance2,MUIA_String_Integer,&tmp2);
  2745.             set(BT_Ok,MUIA_Disabled,
  2746.               (fromcity==(UWORD)-1 || tocity==(UWORD)-1 ||
  2747.               viacity==(UWORD)-1 || !tmp || !tmp2));
  2748.             break;
  2749.           
  2750.           case BR_DIST2:
  2751.             get(CB_Lock2,MUIA_Selected,&i);
  2752.             if(i)
  2753.               {
  2754.               get(ST_Distance2,MUIA_String_Integer,&i);
  2755.               tmp=ConvertDist(distance,rd[rte].Units,MeasureUnits);
  2756.               i=(i>tmp ? tmp : i);
  2757.               set(ST_Distance2,MUIA_String_Integer,i);
  2758.               set(ST_Distance1,MUIA_String_Integer,tmp-i);
  2759.               }
  2760.             
  2761.             get(ST_Distance1,MUIA_String_Integer,&tmp);
  2762.             get(ST_Distance2,MUIA_String_Integer,&tmp2);
  2763.             set(BT_Ok,MUIA_Disabled,
  2764.               (fromcity==(UWORD)-1 || tocity==(UWORD)-1 ||
  2765.               viacity==(UWORD)-1 || !tmp || !tmp2));
  2766.             break;
  2767.           
  2768.           case BR_MEASUREUNITS:
  2769.             get(CY_MeasureUnits,MUIA_Cycle_Active,&i);
  2770.             get(CY_Speed1, MUIA_Cycle_Active, &tmp);
  2771.             get(CY_Speed2, MUIA_Cycle_Active, &tmp2);
  2772.             
  2773.             settext(TX_Dist1Units, distlabels[i]);
  2774.             settext(TX_Dist2Units, distlabels[i]);
  2775.             
  2776.             if(tmp==USE_TIME)
  2777.               settext(TX_Speed1Units, speedlabels[2]);
  2778.             else
  2779.               settext(TX_Speed1Units, speedlabels[i]);
  2780.             
  2781.             if(tmp2==USE_TIME)
  2782.               settext(TX_Speed2Units, speedlabels[2]);
  2783.             else
  2784.               settext(TX_Speed2Units, speedlabels[i]);
  2785.             
  2786.             if(i!=MeasureUnits)
  2787.               {
  2788.               ULONG tval;
  2789.               
  2790.               get(ST_Distance1, MUIA_String_Integer, &tval);
  2791.               
  2792.               tval=ConvertDist(tval,MeasureUnits,i);
  2793.               
  2794.               set(ST_Distance1, MUIA_String_Integer, tval);
  2795.               
  2796.               get(ST_Distance2, MUIA_String_Integer, &tval);
  2797.               
  2798.               tval=ConvertDist(tval,MeasureUnits,i);
  2799.               
  2800.               set(ST_Distance2, MUIA_String_Integer, tval);
  2801.               
  2802.               if(tmp!=USE_TIME)
  2803.                 {
  2804.                 get(ST_Speed1, MUIA_String_Integer, &tval);
  2805.                 
  2806.                 tval=ConvertDist(tval,MeasureUnits,i);
  2807.                 
  2808.                 set(ST_Speed1, MUIA_String_Integer, tval);
  2809.                 }
  2810.               
  2811.               if(tmp2!=USE_TIME)
  2812.                 {
  2813.                 get(ST_Speed2, MUIA_String_Integer, &tval);
  2814.                 
  2815.                 tval=ConvertDist(tval,MeasureUnits,i);
  2816.                 
  2817.                 set(ST_Speed2, MUIA_String_Integer, tval);
  2818.                 }
  2819.               
  2820.               MeasureUnits=i;
  2821.               }
  2822.             break;
  2823.           }
  2824.         
  2825.         if(going && sigs) Wait(sigs);
  2826.         }
  2827.       }
  2828.     else
  2829.       MUI_Request(app,mainwindow,0,NULL,"_Ok","Couldn't open break window.");
  2830.     
  2831.     set(editwindow,MUIA_Window_Open,FALSE);
  2832.     DoMethod(app,OM_REMMEMBER,editwindow);
  2833.     MUI_DisposeObject(editwindow);
  2834.     
  2835.     set(app,MUIA_Application_Sleep,FALSE);
  2836.     }
  2837.   else
  2838.     MUI_Request(app,mainwindow,0,NULL,"_Ok","Couldn't create break window.");
  2839.   
  2840.   ReLink();
  2841.   return retval;
  2842. }
  2843.  
  2844. #define IR_OK        (400)
  2845. #define IR_CANCEL    (401)
  2846.  
  2847. ULONG InfoRequester(char *filename, BOOL mpr)
  2848. {
  2849.   APTR infowindow, ST_Name, ST_EMail, TX_Cities, TX_Routes;
  2850.   APTR TX_GfxMem, TX_OtherMem, BT_Ok, BT_Cancel;
  2851.   char *str, tbuf[100];
  2852.   int i, sigs;
  2853.   BOOL going=TRUE;
  2854.   ULONG retval;
  2855.   
  2856.   retval=mpr;
  2857.   
  2858.   infowindow=WindowObject,
  2859.                MUIA_Window_Title,       "Information",
  2860.                MUIA_Window_ScreenTitle, COPYRIGHT,
  2861.                MUIA_Window_ID,          400,
  2862.                MUIA_Window_NoMenus,     TRUE,
  2863.                MUIA_HelpNode,           "DBaseInfo",
  2864.                
  2865.                WindowContents,
  2866.                VGroup,
  2867.                  Child, ColGroup(2),
  2868.                    Child, Label1("Database:"),
  2869.                    Child, SimpleText(filename),
  2870.                    Child, Label1("Cities:"),
  2871.                    Child, TX_Cities=SimpleText(""),
  2872.                    Child, Label1("Routes:"),
  2873.                    Child, TX_Routes=SimpleText(""),
  2874.                    Child, Label1("Graphics memory:"),
  2875.                    Child, TX_GfxMem=SimpleText(""),
  2876.                    Child, Label1("Other memory:"),
  2877.                    Child, TX_OtherMem=SimpleText(""),
  2878.                    Child, KeyLabel2("Author:",'a'),
  2879.                    Child, ST_Name=KeyString(dbi.dbi_Author,60,'a'),
  2880.                    Child, KeyLabel2("Email address:",'e'),
  2881.                    Child, ST_EMail=KeyString(dbi.dbi_EMail,60,'e'),
  2882.                    End,
  2883.                  Child, HGroup,
  2884.                    MUIA_Group_SameSize, TRUE,
  2885.                    Child, BT_Ok=KeyButton("Ok",'o'),
  2886.                    Child, BT_Cancel=KeyButton("Cancel",'c'),
  2887.                    End,
  2888.                  End,
  2889.                End;
  2890.   
  2891.   if(infowindow)
  2892.     {
  2893.     DoMethod(app,OM_ADDMEMBER,infowindow);
  2894.     
  2895.     SPrintf(tbuf,"%ld",cdcount);
  2896.     settext(TX_Cities,tbuf);
  2897.     
  2898.     SPrintf(tbuf,"%ld",rdcount);
  2899.     settext(TX_Routes,tbuf);
  2900.     
  2901.     SPrintf(tbuf,"%lUk",AvailMem(MEMF_CHIP)/1024);
  2902.     settext(TX_GfxMem,tbuf);
  2903.     
  2904.     SPrintf(tbuf,"%lUk",AvailMem(MEMF_FAST)/1024);
  2905.     settext(TX_OtherMem,tbuf);
  2906.     
  2907.     StringReturn(ST_Name,infowindow);
  2908.     StringBehave(ST_EMail,IR_OK);
  2909.     
  2910.     ButtonBehave(BT_Ok, IR_OK);
  2911.     ButtonBehave(BT_Cancel, IR_CANCEL);
  2912.     
  2913.     DoMethod(infowindow,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
  2914.       app,2,MUIM_Application_ReturnID,IR_CANCEL);
  2915.     
  2916.     DoMethod(infowindow,MUIM_Window_SetCycleChain,ST_Name,ST_EMail,NULL);
  2917.     
  2918.     set(infowindow,MUIA_Window_Open,TRUE);
  2919.     get(infowindow,MUIA_Window_Open,&i);
  2920.     if(i)
  2921.       {
  2922.       while(going)
  2923.         {
  2924.         switch(DoMethod(app,MUIM_Application_Input,&sigs))
  2925.           {
  2926.           case 0:
  2927.             break;
  2928.           
  2929.           case QUIT:
  2930.             retval=QUIT;
  2931.             going=FALSE;
  2932.             break;
  2933.           
  2934.           case IR_OK:
  2935.             get(ST_Name,MUIA_String_Contents,&str);
  2936.             strcpy(dbi.dbi_Author,str);
  2937.             
  2938.             get(ST_EMail,MUIA_String_Contents,&str);
  2939.             strcpy(dbi.dbi_EMail,str);
  2940.             
  2941.             retval=TRUE;
  2942.             going=FALSE;
  2943.             break;
  2944.           
  2945.           case IR_CANCEL:
  2946.             retval=mpr;
  2947.             going=FALSE;
  2948.             break;
  2949.           }
  2950.         
  2951.         if(sigs && going) Wait(sigs);
  2952.         }
  2953.       
  2954.       set(infowindow,MUIA_Window_Open,FALSE);
  2955.       }
  2956.     
  2957.     DoMethod(app,OM_REMMEMBER,infowindow);
  2958.     MUI_DisposeObject(infowindow);
  2959.     }
  2960.   
  2961.   return retval;
  2962. }
  2963.